当前位置:   article > 正文

用C++写一个小游戏——扫雷(1)_扫雷c++

扫雷c++

一、项目准备

1、安装VS2022

(1)从官网下载Visal Studio(Community 2022):

Visual Studio 2022 IDE - 适用于软件开发人员的编程工具 (microsoft.com)https://visualstudio.microsoft.com/zh-hans/vs/

(2)安装Visal Studio

 下载完成后,启动下载的 VisualStudioSetup.exe

  • 工作负荷 选择 “使用C++的桌面开发” 即可,其他看个人需求。

  •  在 安装位置 将位置改为D盘(C盘充足的可忽略这步)

  •  点击安装

2、安装Easyx

(1)从官网下载Easyx库
EasyX Graphics Library for C++https://easyx.cn/

        进入官网后点击 “下载EasyX” 即可下载

(2)安装EasyX库

双击下载的程序会进入安装导向

选择 下一步,找到刚刚下载的VS2022,点击 安装 即可

 

3、准备好游戏需要用到的图片

图片压缩包
提取码:3mp1 

将下载完的图片文件夹 images,复制到 与扫雷.cpp同一级 的目录下

 二、项目的编写

1、创建项目

  • 双击安装好的VS2022,进入以下界面,点击 创建新项目 

  • 选择 空项目 ,点击 下一步

  •  将项目名称改为你想要的名字,位置选择平常放置代码的位置即可,点击 创建
  •  项目创建成功

  • 在右边的源文件中右击->添加->新建项 ,进入下面界面

  • 选择 C++文件(.cpp),名称改为 扫雷.cpp
  • 添加成功

 

 2、编写项目

 (1)包含头文件

  1. #include<iostream>
  2. #include<stdlib.h>
  3. #include<time.h>
  4. #include<easyx.h>
  5. #include<graphics.h>
  6. using namespace std;

 (2)宏定义游戏的参数

  1. #define ROW 10 // 地图的行
  2. #define COL 10 // 地图的列
  3. #define BOOM 10 // 雷的个数
  4. #define IMGW 40 // 图片的宽度

(3)声明函数所调用的函数

  1. void showMap (int map[ROW][COL]); // 打印地图数据
  2. void initMap (int map[ROW][COL]); // 初始化地图
  3. void mouseEvent (int map[ROW][COL]); // 鼠标操作
  4. void drawMap (int map[ROW][COL], IMAGE img[]); // 绘制地图
  5. void openNull (int map[ROW][COL], int row, int col); // 炸开空白格子周围的非雷格子
  6. void judge (int map[ROW][COL], int row, int col); // 判断是否点到雷
  7. void judge_game(int map[ROW][COL]); // 判断游戏是否结束、胜利

(4)定义游戏所需的标志位

  1. bool isOver = false; // 游戏结束标志位
  2. int flag = 0; // 已经点开的非雷格子数,如果格子数达到(ROW*COL-BOOM)(这里是90),就胜利

(5)打印游戏的数据

  1. //打印游戏的数据
  2. void showMap(int map[ROW][COL])
  3. {
  4. for (int i = 0; i < ROW; i++)
  5. {
  6. for (int j = 0; j < COL; j++)
  7. {
  8. printf("%2d ",map[i][j]);
  9. }
  10. printf("\n");
  11. }
  12. printf("\n");
  13. }

(6)初始化地图:在地图中100个格子里随机埋下10个雷,并将雷所在九宫格的所有格子的数值+1,雷除外

  1. void initMap(int map[ROW][COL])
  2. {
  3. //给地图埋10个雷,雷用-1表示
  4. for (int i = 0; i < BOOM; )
  5. {
  6. int r = rand() % ROW;
  7. int c = rand() % COL;
  8. if (map[r][c] == 0)
  9. {
  10. map[r][c] = -1;
  11. i++; //只有成功设置了雷,才自增
  12. }
  13. }
  14. //雷所在的九宫格所有的格子的数值都+1,雷除外
  15. for (int i = 0; i < ROW; i++)
  16. {
  17. for (int j = 0; j < COL; j++)
  18. {
  19. if (map[i][j] == -1)
  20. {
  21. //遍历雷所在的九宫格
  22. for (int r = i - 1; r <= i + 1; r++)
  23. {
  24. for (int c = j - 1; c <= j + 1; c++)
  25. {
  26. //除了雷之外的格子,数值都+1
  27. if ((r >= 0 && r < ROW && c >= 0 && c < COL) && map[r][c] != -1)
  28. {
  29. map[r][c] ++;
  30. }
  31. }
  32. }
  33. }
  34. }
  35. }
  36. //把所有的格子都用遮图盖起来,给每个格子都加密,比如都加上20
  37. for (int i = 0; i < ROW; i++)
  38. {
  39. for (int j = 0; j < ROW; j++)
  40. {
  41. map[i][j] += 20;
  42. }
  43. }
  44. }

(7)绘制地图

  1. void drawMap(int map[ROW][COL],IMAGE img[])
  2. {
  3. //把数组里的数据转换成对应的图片,贴图贴到图形窗口上面
  4. for (int i = 0; i < ROW; i++)
  5. {
  6. for (int j = 0; j < ROW; j++)
  7. {
  8. //空白格子和数字
  9. if (map[i][j] >= 0 && map[i][j] <= 8)
  10. {
  11. putimage(j * IMGW, i * IMGW, img + map[i][j]);
  12. }
  13. //雷,贴上雷图
  14. else if (map[i][j] == -1)
  15. {
  16. putimage(j * IMGW, i * IMGW, img + 9);
  17. }
  18. //没被点开的格子,贴上遮盖图
  19. else if (map[i][j] >= 19 && map[i][j] <= 28)
  20. {
  21. putimage(j * IMGW, i * IMGW, img + 10);
  22. }
  23. //右键标记,贴上标记图
  24. else if (map[i][j] == -2)
  25. {
  26. putimage(j * IMGW, i * IMGW, img + 11);
  27. }
  28. }
  29. }
  30. }

(8)鼠标操作

  1. void mouseEvent(int map[ROW][COL])
  2. {
  3. //定义消息结构体(鼠标、按键、字符消息)
  4. ExMessage msg;
  5. //如果有消息,会返回真,并且会给msg设置值
  6. if (peekmessage(&msg,EM_MOUSE))
  7. {
  8. //把鼠标的坐标转换成下标
  9. int c = msg.x / IMGW;
  10. int r = msg.y / IMGW;
  11. if (msg.message == WM_LBUTTONDOWN) //如果鼠标左击,
  12. {
  13. if (map[r][c] >= 19 && map[r][c] <= 28) // 如果该格子没有点开,则允许点开格子
  14. {
  15. flag++;
  16. map[r][c] -= 20;
  17. openNull(map, r, c);
  18. judge(map, r, c);
  19. showMap(map);
  20. }
  21. else if (map[r][c] == -2) //如果已经被标记为雷,还左击则游戏结束
  22. {
  23. flag++;
  24. map[r][c] = -1;
  25. judge(map, r, c);
  26. showMap(map);
  27. }
  28. }
  29. else if (msg.message == WM_RBUTTONDOWN) //如果鼠标右击,则显示标记图
  30. {
  31. if (map[r][c] >= 19 && map[r][c] <= 28)
  32. {
  33. map[r][c] = -2;
  34. showMap(map);
  35. }
  36. }
  37. }
  38. }

(9)打开空白格子时炸开空白格子周围的非雷格子

  1. void openNull(int map[ROW][COL], int row, int col)
  2. {
  3. //判断当前点击的是否为空白
  4. if (map[row][col] == 0)
  5. {
  6. //遍历周围九宫格
  7. for (int i = row - 1; i <= row + 1; i++)
  8. {
  9. for (int j = col - 1; j <=col + 1; j++)
  10. {
  11. //如果有没点开的非雷格子,就把它炸开(显示出来)
  12. if ((i >= 0 && i< ROW && j >= 0 && j < COL) && map[i][j] >= 19 && map[i][j] <= 28)
  13. {
  14. map[i][j] -= 20;
  15. flag++;
  16. openNull(map, i, j); //如果炸开的是空白格子,递归实现连续炸开
  17. }
  18. }
  19. }
  20. }
  21. }

(10)判断是否点到雷

  1. void judge(int map[ROW][COL], int row, int col)
  2. {
  3. //如果点到雷,就game over ,点一个雷其他的雷都显示出来
  4. if (map[row][col] == -1)
  5. {
  6. //遍历显示地图中的所有的雷
  7. for (int i = 0; i < ROW; i++)
  8. {
  9. for (int j = 0; j < COL; j++)
  10. {
  11. if (map[i][j] == 19)
  12. {
  13. map[i][j] -= 20;
  14. flag = 0;
  15. }
  16. }
  17. }
  18. isOver = true;
  19. }
  20. }

(11)判断游戏是否结束

  1. void judge_game(int map[ROW][COL])
  2. {
  3. //输了,点到雷
  4. if (isOver)
  5. {
  6. int ret = MessageBox(GetHWnd(), "你已经输了,是否继续游戏?", "hit", MB_OKCANCEL); //显示提示窗口:已经输了,是否继续游戏
  7. if (ret == IDOK) //如果左击确定,重新初始化地图
  8. {
  9. //把map清零
  10. memset(map, 0, ROW * COL * sizeof(int));
  11. initMap(map);
  12. showMap(map);
  13. isOver = false;
  14. }
  15. else if (ret == IDCANCEL) //如果左击退出,退出程序
  16. {
  17. exit(666);
  18. }
  19. }
  20. //赢了,点了所有非雷的点就赢了
  21. if (flag == (ROW * COL - BOOM))
  22. {
  23. int ret = MessageBox(GetHWnd(), "你已经赢了,是否继续游戏?", "666", MB_OKCANCEL); //显示提示窗口:已经赢了,是否继续游戏
  24. if (ret == IDOK) //如果左击确定,重新初始化地图
  25. {
  26. //把map清零
  27. flag = 0;
  28. memset(map, 0, ROW * COL * sizeof(int));
  29. initMap(map);
  30. showMap(map);
  31. isOver = false;
  32. }
  33. else if (ret == IDCANCEL) //如果左击退出,退出程序
  34. {
  35. exit(666);
  36. }
  37. }
  38. }

(12)主函数

  1. int main()
  2. {
  3. IMAGE img[12]; // 定义图片数组
  4. int map[ROW][COL] = { 0 }; // 定义游戏的地图
  5. initgraph(COL*IMGW, ROW*IMGW, EW_SHOWCONSOLE); // 创建图形窗口
  6. srand((unsigned)time(NULL)); // 设置随机数种子
  7. initMap(map); // 初始化地图
  8. for (int i = 0; i < 12; i++) // 加载图片
  9. {
  10. char fileName[50] = { 0 };
  11. sprintf_s(fileName,"./images/%d.png", i);
  12. loadimage(img + i, fileName, IMGW, IMGW);
  13. }
  14. while (1)
  15. {
  16. mouseEvent(map); //鼠标操作
  17. drawMap(map, img); //绘制地图
  18. judge_game(map); //判断游戏是否结束、胜利
  19. }
  20. return 0;
  21. }

3、运行项目

(1)在VS2022的上方,点击 本地Windows 调试器 运行项目

 (2)运行结果

 

这样,一个简单的扫雷小游戏就完成了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/90860
推荐阅读
相关标签
  

闽ICP备14008679号