百行代码手撸扫雷(下)c/c++

  • 在上一篇文章中已经带大家如何搭建开发环境了

需求分析

  • 这里是一个8*8的地图
    在这里插入图片描述

地雷随机分布数字表示周围一共有多少颗雷

在这里插入图片描述

数字1表示红色区域内有1课雷,2表示有两颗

在这里插入图片描述

在这里插入图片描述

如何显示数字

在这里插入图片描述
右上角没有如何判断呢?行加1或列加一不就越界了吗,所以为了帮面条件判断我们把8行8列改成10行10列

在这里插入图片描述

游戏实现

  • 先包含头文件

  • #include <SFML/Graphics.hpp>

  • #include <SFML/Audio.hpp>

  • 初始化窗口大小,就类似于我们要搭台唱戏一样,需要一个舞台这个舞台大小需要多大,我们需要指定一下舞台大小,不指定怎么知道需要多大的舞台呢?这就是初始化

  • 初始化窗口: RenderWindow window(VideoMode(800, 800), “Canxin-MINE”);

  • RenderWindow window(VideoMode(窗口宽度,窗口高度),“窗口右上角的描述信息”);
    宽为x坐标,高为y坐标;

在这里插入图片描述

  • 获取当前鼠标点击的x坐标和y坐标

  • Vector2i pos = Mouse::getPosition(window);

  • 我们要把鼠标的x坐标和y坐标转化成行和列,就需要鼠标的x坐标除以方块的像素宽度,y坐标也是一样

  • 在这里插入图片描述

#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <time.h>

using namespace sf;

#define SIZE 10      //地图宽度

enum {
    NONE_MINE = 0,
    MINE = 9, //地雷
    GROUND,  //地面
    FLAG     //旗帜
};

enum {
    SUCCESS,
    FAILURE,
    GOING
};

int unitSize = 64;
int mineData[SIZE + 2][SIZE + 2];  // 0:没有雷 9:有雷(以避免和雷的数字提示混淆)
int showData[SIZE + 2][SIZE + 2];
int mineCount = 0;

bool success_flag = false;
bool failure_flag = false;

void initMine() {
    //布雷
    for (int i = 1; i <= SIZE; i++) {
        for (int j = 1; j <= SIZE; j++) {
            showData[i][j] = GROUND; // 设置为未点击状态(“地面”)
            //布雷
            if (rand() % 5 == 0) {
                mineData[i][j] = MINE;
                mineCount++;
            }
            else {
                mineData[i][j] = NONE_MINE;
            }
        }
    }

    // 计算雷周围位置的数字显示
    for (int i = 1; i <= SIZE; i++)
        for (int j = 1; j <= SIZE; j++)
        {
            int n = 0;
            if (mineData[i][j] == MINE) continue;
            if (mineData[i + 1][j] == MINE) n++;
            if (mineData[i][j + 1] == MINE) n++;
            if (mineData[i - 1][j] == MINE) n++;
            if (mineData[i][j - 1] == MINE) n++;
            if (mineData[i + 1][j + 1] == MINE) n++;
            if (mineData[i - 1][j - 1] == MINE) n++;
            if (mineData[i - 1][j + 1] == MINE) n++;
            if (mineData[i + 1][j - 1] == MINE) n++;
            mineData[i][j] = n;
        }
}

int check(RenderWindow* window) {
    int count = 0;

    for (int i = 1; i <= SIZE; i++) {
        for (int j = 1; j <= SIZE; j++) {
            if (mineData[i][j] == MINE && showData[i][j] == FLAG) {
                count++;
                continue;
            }
            else if (mineData[i][j] == MINE && showData[i][j] == MINE) {
                failure_flag = true;
                return FAILURE;
            }
        }
    }

    if (count == mineCount) {
        success_flag = true;
        return SUCCESS;
    }

    return GOING;
}

int main()
{
    srand(time(0));

    RenderWindow window(VideoMode(800, 800), "Canxin-MINE");    //初始化窗口

    //加载图片
    Texture t;
    t.loadFromFile("images/tiles2.jpg");
    Sprite s(t);

    //布雷
    initMine();

    Texture t1, t2;
    t1.loadFromFile("images/victory.png");
    t2.loadFromFile("images/fail.png");
    Sprite spriteVictory(t1);
    Sprite spriteFail(t2);

    Sound soundOK;
    SoundBuffer buff1;
    buff1.loadFromFile("OK.wav");
    soundOK.setBuffer(buff1);

    Sound soundFail;
    SoundBuffer buff2;
    buff2.loadFromFile("bom.wav");
    soundFail.setBuffer(buff2);



    while (window.isOpen())
    {
        // 获取鼠标在游戏窗口内的位置坐标
        Vector2i pos = Mouse::getPosition(window);
        int x = pos.x / unitSize;
        int y = pos.y / unitSize;

        int ret = -1;

        Event e;
        while (window.pollEvent(e))
        {
            if (x <= 0 || x > SIZE || y <= 0 || y > SIZE) {
                break;
            }

            if (e.type == Event::Closed) //关闭窗口按钮
                window.close();

            if (e.type == Event::MouseButtonPressed) {
                if (e.key.code == Mouse::Left) showData[x][y] = mineData[x][y];
                else if (e.key.code == Mouse::Right) showData[x][y] = FLAG;

                ret = check(&window);
            }
        }

        // 清除屏幕
        window.clear(Color::Yellow);

        // 绘制雷区的各方块
        for (int i = 1; i <= SIZE; i++) {
            for (int j = 1; j <= SIZE; j++) {
                if (showData[x][y] == 9) showData[i][j] = mineData[i][j];
                s.setTextureRect(IntRect(showData[i][j] * unitSize, 0, unitSize, unitSize));
                s.setPosition(i * unitSize, j * unitSize);
                window.draw(s);
            }
        }

        //int ret = check(&window);
        if (success_flag) {
            spriteVictory.setPosition(250, 250);
            window.draw(spriteVictory);

        }

        if (failure_flag) {
            spriteFail.setPosition(250, 250);
            window.draw(spriteFail);
        }

        if (ret == FAILURE) {
            soundFail.play();
        }
        else if (ret == GOING) {
            soundOK.play();
        }

        // 刷新显示
        window.display();
    }
      //奇牛学院-残芯
    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_46464021/article/details/106907328