功能实现

  1. 雷的布置
  2. 游戏界面绘制

游戏数值

地雷布置

void Game::mineSet(int pY, int pX) {
    int mCount, i, j, k, l;
    mCount = 0;
    srand(time(NULL));        //用当前时间作为随机数生成器的种子
    do {
        bool flag = true;        //当次循环是否需要布雷
        k = rand() % stageHeight;    //生成随机数
        l = rand() % stageWidth;
        if (abs(k - pY) <= 1 && abs(l - pX) <= 1) {
            flag = false;
        }
        if (flag && mGameData[k][l].mState == ncUNDOWN) {
            mGameData[k][l].mState = ncMINE;
            mGameData[k][l].mStateBackUp = ncMINE;    //备份状态
            mCount++;
        }
    }
    while (mCount != mMineNum);
    //方格赋值
    for (i = 0; i < stageHeight; i++) {
        for (j = 0; j < stageWidth; j++) {
            if (mGameData[i][j].mState != ncMINE) {
                mCount = 0;
                for (k = i - 1; k < i + 2; k++) {
                    for (l = j - 1; l < j + 2; l++) {
                        if (k >= 0 && k < stageHeight && l >= 0 && l < stageWidth) {
                            if (mGameData[k][l].mState == ncMINE) {
                                mCount++;
                            }    //计算周围雷的数目
                        }
                    }
                }
                switch (mCount) {
                    case 0:
                        mGameData[i][j].mState = ncNull; break;
                    case 1:
                        mGameData[i][j].mState = ncONE; break;
                    case 2:
                        mGameData[i][j].mState = ncTWO; break;
                    case 3:
                        mGameData[i][j].mState = ncTHREE; break;
                    case 4:
                        mGameData[i][j].mState = ncFOUR; break;
                    case 5:
                        mGameData[i][j].mState = ncFIVE; break;
                    case 6:
                        mGameData[i][j].mState = ncSIX; break;
                    case 7:
                        mGameData[i][j].mState = ncSEVEN; break;
                    case 8:
                        mGameData[i][j].mState = ncEIGHT; break;
                    default:
                        break;
                }
            }
        }
    }
}    //布雷

图形绘制

总绘制

void Game::Draw() {
    window.clear();                    //清屏
    sBackground.setPosition(0, 0);
    window.draw(sBackground);        //绘制背景
    drawGrid();                        //绘制舞台
    drawButton();                    //绘制按钮
    drawScore();                    //绘制分数
    drawTimer();                    //绘制计时器
    if (isGameOverState) {
        drawGameEnd();
    }
    window.display();
}

网格绘制

void Game::drawGrid() {
    int i, j;
    for (i = 0; i < stageWidth; i++) {
        for (j = 0; j < stageWidth; j++) {
            if (mGameData[j][i].isPress) {
                sTiles.setTextureRect(IntRect(mGameData[j][i].mState * GRIDSIZE, 0, GRIDSIZE, GRIDSIZE));
                sTiles.setPosition(mCornPoint.x + i * GRIDSIZE, mCornPoint.y + j * GRIDSIZE);
            } else {
                sTiles.setTextureRect(IntRect(ncUNDOWN * GRIDSIZE, 0, GRIDSIZE, GRIDSIZE));
                sTiles.setPosition(mCornPoint.x + i * GRIDSIZE, mCornPoint.y + j * GRIDSIZE);
            }
            window.draw(sTiles);
        }
    }
}

按钮绘制

void Game::drawButton() {
    Vector2i leftCorner;
    int buttonWidth = 60;
    int buttonHeight = 36;
    int detaX = (windowWidth - buttonWidth * 7) / 8;    //7个按钮等分宽度
    leftCorner.y = windowHeight - GRIDSIZE * 3;        //指定高度
    for (int i = 0; i < 7; i++) {
        leftCorner.x = (i + 1) * detaX;
        sButtons.setTextureRect(IntRect(i * buttonWidth, 0, buttonWidth, buttonHeight));
        sButtons.setPosition(leftCorner.x, leftCorner.y);
        switch (i) {
            case 0:
                buttonRectEasy.left = leftCorner.x;
                buttonRectEasy.top = leftCorner.y;
                buttonRectEasy.width = buttonWidth;
                buttonRectEasy.height = buttonHeight;
                break;
            case 1:
                buttonRectNormal.left = leftCorner.x;
                buttonRectNormal.top = leftCorner.y;
                buttonRectNormal.width = buttonWidth;
                buttonRectNormal.height = buttonHeight;
                break;
            case 2:
                buttonRectHard.left = leftCorner.x;
                buttonRectHard.top = leftCorner.y;
                buttonRectHard.width = buttonWidth;
                buttonRectHard.height = buttonHeight;
                break;
            case 3:
                buttonRectBG.left = leftCorner.x;
                buttonRectBG.top = leftCorner.y;
                buttonRectBG.width = buttonWidth;
                buttonRectBG.height = buttonHeight;
                break;
            case 4:
                buttonRectSkin.left = leftCorner.x;
                buttonRectSkin.top = leftCorner.y;
                buttonRectSkin.width = buttonWidth;
                buttonRectSkin.height = buttonHeight;
                break;
            case 5:
                buttonRectRestart.left = leftCorner.x;
                buttonRectRestart.top = leftCorner.y;
                buttonRectRestart.width = buttonWidth;
                buttonRectRestart.height = buttonHeight;
                break;
            case 6:
                buttonRectQuit.left = leftCorner.x;
                buttonRectQuit.top = leftCorner.y;
                buttonRectQuit.width = buttonWidth;
                buttonRectQuit.height = buttonHeight;
                break;
            default:
                break;
        }
        window.draw(sButtons);
    }
}

结束界面绘制

void Game::drawGameEnd() {
    Vector2i leftCorner;
    int buttonWidth = 200;
    int buttonHeight = sGameOver.getLocalBounds().height;
    leftCorner.x = (windowWidth - buttonWidth) / 2;
    leftCorner.y = (windowHeight - buttonHeight) / 2;
    sGameOver.setPosition(leftCorner.x, leftCorner.y);
    if (isGameOverState == ncWin) {
        sGameOver.setTextureRect(IntRect(0 * buttonWidth, 0, buttonWidth, buttonHeight));
    }
    if (isGameOverState == ncLose) {
        sGameOver.setTextureRect(IntRect(1 * buttonWidth, 0, buttonWidth, buttonHeight));
    }
    window.draw(sGameOver);
}

结束界面绘制

void Game::drawScore() {
    Vector2i leftCorner;
    leftCorner.x = windowWidth - sCounter.getLocalBounds().width * 1.25;
    leftCorner.y = sCounter.getLocalBounds().height * 0.5;
    sCounter.setPosition(leftCorner.x, leftCorner.y);    //计数器纹理贴图位置
    window.draw(sCounter);
    int numSize = sNum.getLocalBounds().height;
    leftCorner.x = leftCorner.x + sCounter.getLocalBounds().width - numSize;
    leftCorner.y = leftCorner.y + sCounter.getLocalBounds().height * 0.5 - numSize * 0.5;
    int mScore = mMineNum - mFlagCalc;
    //绘制每一位数字
    int a = mScore % 10;
    for (int i = 1; i < 4; i++) {
        sNum.setTextureRect(IntRect(a * numSize, 0, numSize, numSize));
        sNum.setPosition(leftCorner.x, leftCorner.y);
        window.draw(sNum);
        a = mScore / pow(10, i);
        leftCorner.x -= numSize;
    }
}

计时器绘制

void Game::drawTimer() {
    Vector2i leftCorner;
    leftCorner.x = sTimer.getLocalBounds().width * 0.25;
    leftCorner.y = sTimer.getLocalBounds().height * 0.5;
    sTimer.setPosition(leftCorner.x, leftCorner.y);    //计时器纹理贴图位置
    window.draw(sTimer);
    if (isGameBegin) {
        mTime = gameClock.getElapsedTime().asSeconds();
    }
    int numSize = sNum.getLocalBounds().height;
    leftCorner.x = leftCorner.x + sCounter.getLocalBounds().width - numSize * 1.5;
    leftCorner.y = leftCorner.y + sCounter.getLocalBounds().height * 0.5 - numSize * 0.5;
    int mScore = mTime;
    if (mScore > 999) {
        mScore = 999;
    }
    //绘制每一位数字
    int a = mScore % 10;
    sNum.setTextureRect(IntRect(a * numSize, 0, numSize, numSize));
    sNum.setPosition(leftCorner.x, leftCorner.y);
    window.draw(sNum);
    mScore = mScore / 10;
    a = mScore % 10;
    leftCorner.x = leftCorner.x - numSize;
    sNum.setTextureRect(IntRect(a * numSize, 0, numSize, numSize));
    sNum.setPosition(leftCorner.x, leftCorner.y);
    window.draw(sNum);
    mScore = mScore / 10;
    a = mScore % 10;
    leftCorner.x = leftCorner.x - numSize;
    sNum.setTextureRect(IntRect(a * numSize, 0, numSize, numSize));
    sNum.setPosition(leftCorner.x, leftCorner.y);
    window.draw(sNum);
}

效果

可以看到,游戏界面已经被我们完全绘制出来了

Last modification:July 12th, 2020 at 01:06 am