当前位置:首页 » 《随便一记》 » 正文

扫雷c++分板块详解(附源代码及图片素材)

27 人参与  2024年03月04日 09:16  分类 : 《随便一记》  评论

点击全文阅读


扫雷想必是大家小时候玩过的很经典的一款游戏,今天我就将其源代码及图片素材分享出来,供大家学习和参考,如若文案有错落的地方,还望大家指正。

目录

一.准备工作:

二.数组:初始化数表

1.用memset函数先全部初始化为0

2.布置雷

3.统计有多少个雷

4.“加密”处理

三.图像准备

四.数据的接收与处理

1.数据的接收与“打印”

2.数据处理

五.判断输赢与对话框

1.输赢

2.输赢之后的对话框

六.插入背景音乐

七.完整代码分享


一.准备工作:

(1)由于要包含<easyx.h>头文件,在c++环境下,检查自己有没有下载EasyX,没有则需到官网进行下载:EasyX Graphics Library for C++

(2)vs环境下,  E0167    "const char *" 类型的实参与 "LPCWSTR" 类型的形参不兼容   , C2664    “MCIERROR mciSendStringW(LPCWSTR,LPWSTR,UINT,HWND)”: 无法将参数 1 从“const char [35]”转换为“LPCWSTR”    等问题可以通过修改项目属性解决。

1.项目-->属性-->配置属性-->高级-->字符集改成使用多字节字符集

2.项目-->属性-->C/C++ --> 语言-->符合模式改成否

(3)扫雷也肯定需要图片贴纸,下面是我为大家提供的图片素材,至于背景音乐,自己准备。   

https://pan.baidu.com/s/1eUqI1q81Etqf75U_eRG4RA 

提取码:ux3c

//先提前定义常量#define ROW 9#define COL 9#define mine 10    //雷的数量#define imgw 40    //图像的尺寸

二.数组:初始化数表

我们想要什么形式的数表?不同的集合的值应对应不同的对象。

首先是雷与不是雷必须区分开。如果-1表示雷,其他数字就必须代表不是雷。

其次,由于游戏规则,我们还要统计格子周围有几个雷,最好0表示周围没有雷,1表示周围有1个雷,2表示有两个……以此类推,方便后续的贴图。我们当然也不是一定需要数表上的数字这么显示,只需要雷的返回值与贴图的下标一一对应即可。

1.用memset函数先全部初始化为0

memset(map, 0, sizeof(int) * ROW * COL);

2.布置雷

我们将雷设置为-1,不是雷设置为0,这样统计雷的个数时,只用在雷的九宫格外围都+1:

srand((unsigned int)time(NULL));  for (int k = 1; k <= mine; k++){int x = rand() % ROW;int y = rand() % COL;if (map[x][y] == 0)   //防止雷少设,达到所有雷全部被安置;map[x][y] = -1;}

放置10个雷,通过rand函数,确定随机雷的坐标。

3.统计有多少个雷

我们只需要以雷为中心,遍历棋盘中每一个元素,如果是雷,就在在九宫格外圈都加1,循环即可。注意到,棋盘的边缘存在越界的问题,故在if判断句里,不仅要保证是雷,而且要保证坐标不越界。

for (int i = 0; i < ROW; i++){for (int j = 0; j < COL; j++){if (map[i][j] == -1){for ( int r = i - 1; r <= i + 1; r++){for (int c = j - 1; c <= j + 1; c++){if ((r >= 0 && r < ROW && c >= 0 && c < COL) && map[r][c] != -1){++map[r][c];}}}}}}


4.“加密”处理

由于我们玩游戏的时候是看不到哪里是雷,哪里不是雷的,有个白色的东西盖住,他的代码实现就必须与雷区分开,与周围有几个雷的区分开,-1表示雷对应1个图像,0~8表示没有雷和周围有几个雷对应9个图像,那我们直接加20,19~28就可以表示在这一段时用白色的盖子盖住。同样的道理,再加20表示右键的小红旗.你可以将这些值理解为门牌号或者一个地址,贴纸具体贴哪张取决于值是什么。

for (int i = 0; i < ROW; i++){for (int j = 0; j < COL; j++){map[i][j] += 20;}}

三.图像准备

我们先创造一个窗口,载入数据

initgraph(ROW * imgw, COL * imgw);loadresource();/void loadresource() {for (int i = 0; i < 12; i++){char path[50] = { 0 };sprintf_s(path, "./images/%d.jpg", i);loadimage(images + i, path, imgw, imgw);}}  

开始根据值进行贴纸:

void draw(int map[][COL]){for (int i = 0; i < ROW; i++){for (int j = 0; j < COL; j++){if (map[i][j] >= 0 && map[i][j] <= 8){putimage(j * imgw, i * imgw, &images[map[i][j]]);}else if (map[i][j] == -1){putimage(j * imgw, i * imgw, &images[9]);}else if (map[i][j] >= 19 && map[i][j] <= 28){putimage(j * imgw, i * imgw, &images[10]);}else if (map[i][j] >= 39){putimage(j * imgw, i * imgw, &images[11]);}}}}

四.数据的接收与处理

1.数据的接收与“打印”

接收--》处理---》打印

while (true){ExMessage msg;while (peekmessage(&msg, EM_MOUSE))  //不断接收数据{switch (msg.message)    //处理鼠标传来的数据{case WM_LBUTTONDOWN:case WM_RBUTTONDOWN:mouseMsg(&msg, map);   //具体如何处理break;}}draw(map);     //最后还是要展现出来,才看得见的。}

2.数据处理

draw(),只是描述了什么时候什么样的值贴什么样的图,只是静态的,数据处理,将值的大小发生改变,贴什么样的图随之改变就实现了将这个过程动起来。

操作对应值的变换,进而对应贴图变换,游戏往前推进。

左键:格子打开,19到28的数,跑到-1到8上对应的数上,贴图随之而变,并且还要实现,如果周围也没有雷,则炸开一片的功能。

右键:插小红旗,19到28的数,跑到29到48上,图由格子变成小红旗

void mouseMsg(ExMessage* msg, int map[][COL]){intc =msg->x / imgw;int r =msg->y / imgw;if (msg->message == WM_LBUTTONDOWN){if (map[r][c] >= 19 && map[r][c] <= 28){map[r][c] -= 20;boomblank(map, r, c);//system("cls");//show(map); }}else if (msg->message == WM_RBUTTONDOWN){if (map[r][c] >= 19 && map[r][c] <= 28){map[r][c] += 20;//system("cls");//show(map);}else if (map[r][c] >= 39){map[r][c] -= 20;//system("cls");//show(map);}}}void boomblank(int map[][COL], int row, int col){if (map[row][col] == 0){for (int i = row - 1; i <= row + 1; i++){for (int j = col - 1; j <= col + 1; j++){if ((i >= 0 && i < ROW && j >= 0 && j < COL) && map[i][j] >= 19 && map[i][j] <= 28){map[i][j] -= 20;boomblank(map, i, j);}}}}}

五.判断输赢与对话框

1.输赢

输了,就是点到雷了,赢了就是雷扫完了,无雷可扫了

int juge(int map[][COL], int row, int col){if (map[row][col] == -1 || map[row][col] == 19){return -1;}int cet = 0;for (int i = 0; i <= ROW; i++){for (int j = 0; j <= COL; j++){if (map[i][j] >= 0 && map[i][j] <= 8)cet++;}}if (ROW * COL - mine == cet){return 1;}return 0;}

2.输赢之后的对话框

输了再来一局,赢了大家也可以自由发挥

int ret =juge(map,msg.y/imgw,msg.x/imgw);if (ret == -1){int select = MessageBox(GetHWnd(), "   您被炸死了\n点击确认再来一局","扫雷", MB_OKCANCEL);if (select == IDOK){init(map);}else{exit(0);}}else if (ret == 1){int select = MessageBox(GetHWnd(), "你赢了\n点击确认再来一局", "扫雷", MB_OKCANCEL);if (select == IDOK){init(map);}else{exit(0);}}

六.插入背景音乐

需先声明#include<mmsystem.h>   #pragma comment(lib,"winmm.lib")

然后再在想要的位置插入  

mciSendString("open ./images/furina.mp3 alias bgm",NULL,0,NULL);mciSendString("play bgm", NULL, 0, NULL);//具体放什么背景音乐,大家下载到对应路径即可

七.完整代码分享

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<stdlib.h>#include<time.h>#include<easyx.h>#include<graphics.h>#include<Windows.h>#include<mmsystem.h>#pragma comment(lib,"winmm.lib")#define ROW 9#define COL 9#define mine 10#define imgw 40IMAGE images[12];void loadresource();  // 导入图像资源void init(int map[][COL]);   //初始化雷void show(int map[][COL]);void draw(int map[][COL]);void mouseMsg(ExMessage* msg, int map[][COL]);void boomblank(int map[][COL], int row, int col);int juge(int map[][COL], int row, int col);int main(){int map[ROW][COL];init(map);//show(map);initgraph(ROW * imgw, COL * imgw);//,EW_SHOWCONSOLEloadresource();mciSendString("open ./images/furina.mp3 alias bgm",NULL,0,NULL);mciSendString("play bgm", NULL, 0, NULL);while (true){ExMessage msg;while (peekmessage(&msg, EM_MOUSE)){switch (msg.message){case WM_LBUTTONDOWN:case WM_RBUTTONDOWN:mouseMsg(&msg, map);int ret =juge(map,msg.y/imgw,msg.x/imgw);if (ret == -1){int select = MessageBox(GetHWnd(), "   您被炸死了\n点击确认再来一局","扫雷", MB_OKCANCEL);if (select == IDOK){init(map);}else{exit(0);}}else if (ret == 1){int select = MessageBox(GetHWnd(), "你赢了\n点击确认再来一局", "扫雷", MB_OKCANCEL);if (select == IDOK){init(map);}else{exit(0);}}break;}}draw(map);}return 0;}void loadresource() {for (int i = 0; i < 12; i++){char path[50] = { 0 };sprintf_s(path, "./images/%d.jpg", i);loadimage(images + i, path, imgw, imgw);}}  void init(int map[][COL]){// 全部初始化为零memset(map, 0, sizeof(int) * ROW * COL);srand((unsigned int)time(NULL));for (int k = 1; k <= mine; k++){int x = rand() % ROW;int y = rand() % COL;if (map[x][y] == 0)   //防止雷少设,达到所有雷全部被安置;map[x][y] = -1;}for (int i = 0; i < ROW; i++){for (int j = 0; j < COL; j++){if (map[i][j] == -1){for ( int r = i - 1; r <= i + 1; r++){for (int c = j - 1; c <= j + 1; c++){if ((r >= 0 && r < ROW && c >= 0 && c < COL) && map[r][c] != -1){++map[r][c];}}}}}}for (int i = 0; i < ROW; i++){for (int j = 0; j < COL; j++){map[i][j] += 20;}}}void show(int map[][COL]){for (int i = 0; i < ROW; i++){for (int j = 0; j < COL; j++){printf("%2d ", map[i][j]);}printf("\n");}}void draw(int map[][COL]){for (int i = 0; i < ROW; i++){for (int j = 0; j < COL; j++){if (map[i][j] >= 0 && map[i][j] <= 8){putimage(j * imgw, i * imgw, &images[map[i][j]]);}else if (map[i][j] == -1){putimage(j * imgw, i * imgw, &images[9]);}else if (map[i][j] >= 19 && map[i][j] <= 28){putimage(j * imgw, i * imgw, &images[10]);}else if (map[i][j] >= 39){putimage(j * imgw, i * imgw, &images[11]);}}}}void mouseMsg(ExMessage* msg, int map[][COL]){intc =msg->x / imgw;int r =msg->y / imgw;if (msg->message == WM_LBUTTONDOWN){if (map[r][c] >= 19 && map[r][c] <= 28){map[r][c] -= 20;boomblank(map, r, c);//system("cls");//show(map); }}else if (msg->message == WM_RBUTTONDOWN){if (map[r][c] >= 19 && map[r][c] <= 28){map[r][c] += 20;//system("cls");//show(map);}else if (map[r][c] >= 39){map[r][c] -= 20;//system("cls");//show(map);}}}void boomblank(int map[][COL], int row, int col){if (map[row][col] == 0){for (int i = row - 1; i <= row + 1; i++){for (int j = col - 1; j <= col + 1; j++){if ((i >= 0 && i < ROW && j >= 0 && j < COL) && map[i][j] >= 19 && map[i][j] <= 28){map[i][j] -= 20;boomblank(map, i, j);}}}}}int juge(int map[][COL], int row, int col){if (map[row][col] == -1 || map[row][col] == 19){return -1;}int cet = 0;for (int i = 0; i <= ROW; i++){for (int j = 0; j <= COL; j++){if (map[i][j] >= 0 && map[i][j] <= 8)cet++;}}if (ROW * COL - mine == cet){return 1;}return 0;}


点击全文阅读


本文链接:http://zhangshiyu.com/post/73297.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1