摆脱黑窗口,我们用easyX图形库做一个我们小时经常玩的扫雷小游戏。在做出来时你会发现,做一个小游戏原来如此简单,最会还有如何打包的教程,打包之后,可以发给朋友玩玩哦,在炫耀技术的同时可以回味一下童年乐趣。
使用了easyX的图形库进行开发的小游戏,不会的可以去看我的easyX图行库学习的文章,很容易上手的,简单看一下就可以写这个程序的,里面用到的图片我都放到资源里面了,直接私信我要也可以 eaxyX图形库学习https://blog.csdn.net/qq_52661581/article/details/125124212?spm=1001.2014.3001.5502
目录
一、包含头文件
#include <stdio.h>
#include <stdlib.h> //使用随机函数rank()
#include <time.h> //使用time()
#include <graphics.h> //使用图行库
#pragma comment(lib,"winmm.lib") //播放音乐
二、全局变量
#define ROW 12 //行 (可以更改)
#define COL 12 //列 (可以更改)
#define NUM 12 //雷的数量 (可以更改)
#define SIZE 50 //图片大小 (可以自己更改)
#define MAX 1 //容错率(即踩到的雷最多的数量)
bool FLAG; //用来表示是否退出
int map[ROW][COL]; //用来存放所有元素
int count; //用来判断所有格子是否都点完
int count_L ; //踩到雷的个数
IMAGE img[12]; //用来放所有图片
三、游戏初始化
//游戏初始化
void GameInit()
{
//随机数种子(使每次布雷的位置不同)
srand((unsigned int)time(NULL));
//播放音乐
mciSendString("open ./BGM.mp3 alias BGM", 0, 0, 0);
mciSendString("play BGM repeat", 0, 0, 0);
FLAG = TRUE; //表示开始
count = 0; //刚开始点了0个格子
count_L = 0; //点出雷的个数
//创建窗口
initgraph(ROW * SIZE, COL * SIZE);
/*图片 0:背景
1-9:数字1-8
10:标记
11:雷 */
loadimage(&img[0], "./tp/back.png", SIZE, SIZE);
loadimage(&img[1], "./tp/0.png", SIZE, SIZE);
loadimage(&img[2], "./tp/1.png", SIZE, SIZE);
loadimage(&img[3], "./tp/2.png", SIZE, SIZE);
loadimage(&img[4], "./tp/3.png", SIZE, SIZE);
loadimage(&img[5], "./tp/4.png", SIZE, SIZE);
loadimage(&img[6], "./tp/5.png", SIZE, SIZE);
loadimage(&img[7], "./tp/6.png", SIZE, SIZE);
loadimage(&img[8], "./tp/7.png", SIZE, SIZE);
loadimage(&img[9], "./tp/8.png", SIZE, SIZE);
loadimage(&img[10], "./tp/a.png", SIZE, SIZE);
loadimage(&img[11], "./tp/err.png", SIZE, SIZE);
//所有元素都赋值为0
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
map[i][j] = 0;
}
}
//布雷用-1表示 NUM个雷
int n = 0;
while (n < NUM)
{
int r = rand() % ROW;
int c = rand() % COL;
if (map[r][c] == 0)
{
map[r][c] = -1;
n++;
}
}
//数字提示(该格周围雷的数量) 如果雷周围的八个格不是雷则加一
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
if (map[i][j] == -1)
{
for (int m = i - 1; m <= i + 1; m++)
{
for (int n = j - 1; n <= j + 1; n++)
{
if ( m >= 0 && n >= 0 && m<ROW && n<COL && map[m][n] != -1)
{
map[m][n]++;
}
}
}
}
}
}
//刚开始所有全部加密
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
map[i][j] += 20;
}
}
}
四、绘图渲染游戏
//使用图片绘制游戏
void GameDraw()
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
if (map[i][j] == -1) //雷
{
putimage(i * SIZE, j * SIZE, &img[11]);
}
else if (map[i][j] >= 0 && map[i][j] <= 8) //数字
{
putimage(i * SIZE, j * SIZE, &img[map[i][j] + 1]);
}
else if (map[i][j] >= 19 && map[i][j] <= 28) //背景图片
{
putimage(i * SIZE, j * SIZE, &img[0]);
}
else
{
putimage(i * SIZE, j * SIZE, &img[10]); //标记图片
}
}
}
}
五、自动解密0周围的格子(使用递归)
//打开0 使用递归
void openZero(int i, int j)
{
for (int m = i - 1; m <= i + 1; m++)
{
for (int n = j - 1; n <= j + 1; n++)
{
if (m >= 0 && n >= 0 && m < ROW && n < COL)
{
if (map[m][n] > 19 && map[m][n] <= 28) //空白的
{
if (map[m][n] != 20) //不是0
{
map[m][n] -= 20; //解密
count++; //每打开一个都要加一
}
else //如果还是0,则再次调用
{
map[m][n] -= 20; //解密
count++; //每打开一个都要加一
openZero(m, n);
}
}
}
}
}
}
六、鼠标消息
//鼠标消息(在easyX中不会的话可以去看看)
void Mouse()
{
MOUSEMSG msg; //用来接收鼠标消息
if (MouseHit()) //当鼠标点击的时候
{
msg = GetMouseMsg(); //接受鼠标消息
if (msg.uMsg == WM_LBUTTONDOWN) //鼠标左键按下
{
if (map[msg.x / SIZE][msg.y / SIZE] >= 19 ) //防止减多次变成雷
{
map[msg.x / SIZE][msg.y / SIZE] -= 20; //解密
if (map[msg.x / SIZE][msg.y / SIZE] >= -1
&& map[msg.x / SIZE][msg.y / SIZE] <= 8)
{
if (map[msg.x / SIZE][msg.y / SIZE] == -1) //雷
{
count_L++; //踩雷数量
}
if (map[msg.x / SIZE][msg.y / SIZE] == 0)
{
openZero(msg.x / SIZE, msg.y / SIZE);
}
count++; //每次解密都要+1
}
}
}
else if (msg.uMsg == WM_RBUTTONDOWN) //鼠标右键按下
{
if(map[msg.x / SIZE][msg.y / SIZE] >= 19
&& map[msg.x / SIZE][msg.y / SIZE] <30)
map[msg.x / SIZE ][msg.y / SIZE ] += 20; //标记小红旗
}
}
}
七、判断成功/失败
//判断是否胜利/失败 (窗口句柄在easyX中有讲不会可以看看)
void isVictory()
{
HWND hw = GetHWnd(); //获得窗口句柄
SetWindowText(hw, "如你所愿的扫雷"); //窗口标题
if (count_L > MAX) //如果踩雷数大于容错率,游戏失败
{
if (MessageBox(hw, "low 你输了", "sao雷", MB_OK) == IDOK) //弹出消息框
{
if (MessageBox(hw, "low 还想再来一把吗", "sao雷", MB_YESNO) == IDYES)
{
GameInit(); //再次初始化,开始游戏
}
else
{
count_L = 0; //踩雷数量
closegraph(); //关闭窗口
FLAG = 0; //退出程序
}
}
}
if (count == (ROW * COL - NUM + count_L)) //所有格数都解密了
{
if (MessageBox(hw, "牛子 胜利了!", "sao雷", MB_OK) == IDOK) //弹出消息框
{
if (MessageBox(hw, "牛子 还想再来一把吗", "sao雷", MB_YESNO) == IDYES)
{
GameInit(); //再次初始化,开始游戏
}
else
{
count = 0; //解密的格数清零
closegraph(); //关闭窗口
FLAG = 0; //退出程序
}
}
}
}
八、主函数
int main()
{
GameInit();
GameDraw();
while (FLAG)
{
Mouse();
GameDraw();
isVictory();
}
return 0;
}
九、运行成功
十、打包游戏
1 新建打包项目
下一步 给项目起名 点击创建
因为我把图片素材放在tp文件夹下,所以需要添加一个子目录
把这个文件夹下的图片添加进来
我的音乐在当前目录下所以直接在当前目录下添加就行
之后在右击 项目输出 主输出
在创建快捷方式
把创建好的快捷方式放到桌面文件夹下
右击项目 点击生成即可
查看输出 这里就可以看到生成安装文件的位置 或者直接在刚刚项目创建的地方找
安装或者给好友发送下面这个即可
tip:我把需要的素材放在资源里面了哦