扫雷游戏
这周查看其它扫雷游戏的代码加上自己的理解写出了扫雷游戏,在这里我分享一下自己的经验,希望对大家有所帮助。
一.这个扫雷游戏与我们传统的扫雷没有什么区别,主要模块有
1.载入图片,使用loadimage()函数实现;
2.数据初始化即把地图的格子初始化为空,使用随机数埋雷记得加上头文件#include<time.h>
随机数的实现:srand((unsigned)time(NULL));
埋雷的实现:
for (i = 0; i < Nbomb;)
{x = rand() %Nbomb;
y = rand() %Nbomb;
if (map[y][x] != 10)
{
map[y][x] = 10;
i++; //不浪费生成雷的个数
}
}
3.画图使用putimage(x左上角坐标,y左上角坐标,图片地址)
举例:画背景图片
putimage(0,0,&background);
4.计算格子周围的8个格子中地雷的数目
int lei_num(int x,int y,int num)
{
int sum;
int nx, ny;
int lei=10;
sum = 0;
for (nx = x - 1; nx <= x + 1; nx++)
{
for (ny = y - 1; ny <= y + 1; ny++)
{
if (map[ny][nx] == lei)
{
sum++;
}
}
}
return sum;
}
5.格子为空的话就显示空格子的图片
6.格子不为空的话就显示数字的图片
例如:
void not_null(int x, int y, int lei)
{
if (lei == 1)
{
map[y][x] = 11;
}
if (lei == 2)
{
map[y][x] = 22;
}
if (lei == 3)
{
map[y][x] = 33;
}
if (lei == 4)
{
map[y][x] = 44;
}
if (lei == 5)
{
map[y][x] = 55;
}
if (lei == 6)
{
map[y][x] = 66;
}
if (lei == 7)
{
map[y][x] = 77;
}
if (lei == 8)
{
map[y][x] = 88;
}
return;
}
7.空格子自动扩展采用递归调用的方法
1.翻开一个格子如果是地雷就退出游戏并显示所有地雷的位置,2.如果不是地雷就检测周围8个格子中地雷的数目,如果有雷就显示雷的个数,并移动鼠标点击下一个位置,3.如果没有雷,就翻开这个格子,以这个格子为中心继续向周围8个格子探测重复步骤2,直到没有空白格产生,移动鼠标点击下一个位置
实现函数:
void duries(int n_x, int n_y, int size)
{
int leis;
int tx, ty;
//对该格子周围的8个格子进行遍历
for (tx = n_x - 1; tx <= n_x + 1; tx++)
{
for (ty = n_y - 1; ty <= n_y + 1; ty++)
{
if (ty == n_y && tx == n_x)
{
mask[ty][tx] = 0;
continue;
}
if (ty > 0 && tx > 0 && tx < Row && ty < Col && mask[ty][tx] == -1)
{
leis = lei_num(tx, ty, size);
mask[ty][tx] = 0;
if (leis>0)
{
not_null(tx, ty, leis);
}
else{
do_null(tx, ty);
duries(tx, ty, Size);
}
}
}
}
}
8.鼠标控制
1.鼠标移动 对鼠标位置进行移动出现选中框时格子变绿。
2.鼠标左键点击
鼠标左键实现翻开格子的功能 ,要实现翻开格子首先该格子不能做标记而且已已翻开的点击没有作用,鼠标左键点击分为两种情况,大家可能都知道就是点中雷和没有点中雷。
没有点中雷:没有雷就翻开并且调用duries(int n_x, int n_y, int size)扩展空白块
点中雷:遍历整个地图显示地雷的位置,并且强制结束游戏
if (m.uMsg == WM_LBUTTONDOWN)
{
x = m.x / 32;
y = m.y / 32;
if (mask[y][x] != 2)
{
//没有雷的情况
if (map[y][x] == 0)
{
map[y][x] = 3; //没有雷就翻开
duries(x, y, Size);
}
for (i = 1; i < 9; i++)
{
if (map[y][x] == 11 * i)
{
mask[y][x] = 0;
}
}
//有雷的情况
if (map[y][x] == 10)
{
for (i = 0; i < Row; i++)
{
for (j = 0; j < Col; j++)
{
if (map[j][i] == 10)
{
if (j == y && i == x)
{
putimage(i * 32 + 1, j * 32 + 1, &bomb1); //红色地雷
}
else if (mask[j][i] == 2)
{
putimage(i * 32 + 1, j * 32 + 1, &Score);
}
else{
putimage(i * 32 + 1, j * 32 + 1, &bomb2); //灰色地雷
}
//Sleep(100);
}
}
}
mark = 1;
}
}
mciSendString("stop fmusic", NULL, 0, NULL);
mciSendString("close fmusic", NULL, 0, NULL);
mciSendString("open .\\audio\\click.wav alias fmusic", NULL, 0, NULL);
mciSendString("play fmusic", NULL, 0, NULL);
}
3.鼠标右键点击做标记
标记分为:红旗和问号
if (m.uMsg == WM_RBUTTONDOWN)
{
x = m.x / 32;
y = m.y / 32;
if (mask[y][x] != 2 && mask[y][x] != 1 && mask[y][x] != 0)
{
mask[y][x] = 2;
}
else if (mask[y][x] == 1)
{
mask[y][x] = -1;
}
else if (mask[y][x] ==2){
mask[y][x] = 1;
}
9.计时模块
计时采用获取系统时间分为分钟和秒钟
void time()
{
int t1, t2;
int i=0, j=0;
int a, b;
SYSTEMTIME ti; //获取系统时间
GetLocalTime(&ti);
int sum = 0;
sum += ti.wHour - start.wHour;
sum *= 60;
sum += ti.wMinute - start.wMinute;
sum *= 60;
sum += ti.wSecond - start.wSecond;
t1 = sum; //秒钟 76371
t2 = sum / 60; //分钟 1274
while(i != 2)
{
if (i == 0)
{
t1 = sum % 60;
}
a = t1 % 10;
putimage(780 - 32 * i, 445, &colock[a]);
t1 = t1 / 10;
i++;
}
while (j != 2)
{
b = t2 % 10;
putimage(700 - 32 * j, 445, &colock[b]);
t2 = t2 / 10;
j++;
}
}
以上就是扫雷游戏的步骤希望对大家有所帮助下面我把结果给大家截图