本文实例为大家分享了Easyx实现扫雷游戏的具体代码,供大家参考,具体内容如下
代码:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<easyx.h>
#include<mmsystem.h>
#pragma comment(lib, "winmm.lib")
#define ROW 10 //定义行列的常量
#define COL 10
#define MineNum 10 //雷的数量
#define ImgSize 40 //图片的尺寸
//定义图片资源
IMAGE imgs[12];
void loadResource()
{
for (int i = 0; i < 12; i++)
{
char imgPath[50] = { 0 };
sprintf_s(imgPath, "./images/%d.jpg", i);
loadimage(&imgs[i], imgPath, ImgSize, ImgSize);
}
}
bool isfirst = true; //是不是第一次进来
//函数声明
void show(int map[][COL]);
void init(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 judge(int map[][COL], int row, int col);
int main()
{
//创建窗口
initgraph(400, 400/*,EW_SHOWCONSOLE*/);
//播放开始音乐
mciSendString("open ./images/start.mp3 alias bgm", NULL, 0, NULL);
mciSendString("play bgm", NULL, 0, NULL);
//扫雷地图
int map[ROW][COL] = {0};
init(map);
//游戏主循环
while (true)
{
//处理消息
ExMessage msg;
while (peekmessage(&msg, EM_MOUSE))
{
switch (msg.message)
{
case WM_LBUTTONDOWN: //鼠标左键和右键点击
case WM_RBUTTONDOWN:
mouseMsg(&msg, map);
int ret = judge(map,msg.y/ImgSize, msg.x / ImgSize); //点击之后判断
if (ret == -1)
{
draw(map);
int select = MessageBox(GetHWnd(), "你这么牛,怎么输了呢?敢再来一把吗?", "low B!", MB_OKCANCEL);
if (select == IDOK) //再来一把
{
//重新初始化
init(map);
}
else //退出
{
exit(0);
}
}
else if(ret == 1)
{
}
system("cls");
printf("judege:%d\n", ret);
show(map);
break;
}
}
draw(map);
}
//show(map);
getchar();
return 0;
}
void show(int map[][COL])
{
for (int i = 0; i < ROW; i++)
{
for (int k = 0; k < COL; k++)
{
printf("%2d ", map[i][k]);
}
printf("\n");
}
}
//初始化数据
void init(int map[][COL])
{
loadResource();
//设置随机数种子
srand((unsigned)time(NULL));
//把map全部初始化为0
memset(map, 0, sizeof(int) * ROW * COL);
//随机设置十个雷 用-1表示
for (int i = 0; i < MineNum; )
{
//数组的有效下标 [0,9]
int r = rand() % ROW;
int c = rand() % COL;
if (map[r][c] == 0)
{
map[r][c] = -1;
//只有执行了这里的代码,才成功设置了雷 -1
i++;
}
}
//把以雷为中心的九宫格数据都+1,雷除外
for (int i = 0; i < ROW; i++)
{
for (int k = 0; k < COL; k++)
{
//找到雷,并遍历雷所在的九宫格
if (map[i][k] == -1)
{
for (int r = i-1; r <= i+1; r++)
{
for (int c = k-1; c <= k+1; c++)
{
//对周围的数据加1,会有一个bug
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 k = 0; k < COL; k++)
{
map[i][k] += 20;
}
}
}
//绘制
void draw(int map[][COL])
{
//贴图,根据map里面的数据,贴对应的图片
for (int i = 0; i < ROW; i++)
{
for (int k = 0; k < COL; k++)
{
if (map[i][k]>=0 && map[i][k]<=8) //[0,8]
{
int index = map[i][k]; //0 1 2 3 4 5 6 7 8
putimage(k * ImgSize, i * ImgSize, &imgs[index]); //
}
else if (map[i][k] == -1)
{
putimage(k * ImgSize, i * ImgSize, &imgs[9]);
}
else if (map[i][k] >= 19 && map[i][k] <= 28)
{
putimage(k * ImgSize, i * ImgSize, &imgs[10]);
}
else if(map[i][k] >= 39) //-1 + 20 +20
{
putimage(k * ImgSize, i * ImgSize, &imgs[11]);
}
}
}
}
//鼠标操作数据
void mouseMsg(ExMessage* msg,int map[][COL])
{
//先根据鼠标点击的坐标求出对应的数组的下标
int r = msg->y / ImgSize;
int c = msg->x / ImgSize;
//左键打开格子
if (msg->message == WM_LBUTTONDOWN)
{
//什么时候能够打开,没有打开的时候就打开
if (map[r][c]>=19 && map[r][c]<=28)
{
//这个函数只能播放wav格式
PlaySound("./images/click.wav", NULL, SND_ASYNC | SND_FILENAME);
map[r][c] -= 20;
boomBlank(map, r, c); //检测一下是不是空白格子,是,炸开
isfirst = true;
}
}
//右键标记格子
else if (msg->message == WM_RBUTTONDOWN)
{
PlaySound("./images/rightClick.wav", NULL, SND_ASYNC | SND_FILENAME);
//是否能够标记:如果没有打开就能标记
if (map[r][c] >= 19 && map[r][c] <= 28)
{
map[r][c] += 20;
}
else if(map[r][c]>=39)
{
map[r][c] -= 20;
}
}
}
//点击空白格子,连环爆开周围的所有空白格子还有数字 row col 是当前点击的格子
void boomBlank(int map[][COL],int row,int col)
{
//判断row col位置是不是空白格子
if (map[row][col] == 0)
{
for (int r = row-1; r <= row+1; r++)
{
for (int c = col-1; c <= col+1; c++)
{
if ((r>=0&&r<ROW&&c>=0&&c<COL) //没越界
&& map[r][c]>=19 && map[r][c]<=28) //没有打开
{
//每一次调用都会播放一下
if (isfirst)
{
PlaySound("./images/search.wav", NULL, SND_ASYNC | SND_FILENAME);
isfirst = false;
}
map[r][c] -= 20;
boomBlank(map, r, c);
}
}
}
}
return;
}
//游戏结束条件 输了返回-1 没结束返回0 赢了返回 1
int judge(int map[][COL],int row ,int col)
{
//点到了雷,结束 输了
if (map[row][col] == -1 || map[row][col] == 19)
{
return -1;
}
//点完了格子,结束 赢了 点开了100 - 10 = 90 个格子
int cnt = 0;
for (int i = 0; i < ROW; i++)
{
for (int k = 0; k < COL; k++)
{
//统计打开的格子的数量
if (map[i][k] >= 0 && map[i][k] <= 8)
{
++cnt;
}
}
}
if (ROW*COL - MineNum == cnt)
{
return 1;
}
return 0;
}