- 在上一篇文章中已经带大家如何搭建开发环境了
需求分析
- 这里是一个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;
}