(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)
今天我们来尝试用easyx图形库实现c语言的扫雷小游戏,相关图片我已经在文中给出
首先就是引用相关头文件
#include<stdio.h>
#include<graphics.h>//图形库文件,便于生成新的窗口
#include<stdlib.h>
#include<time.h>//用于生成随机函数
接着绘制地图,我们定义的扫雷为十行十列, 规定-1为雷,0表示为空白,1,2,3就是对应的数字
#define row 10//行
#define col 10//列int map[row][col] = { 0 };//定义地图
void drawmap()//绘制地图
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf(" %2d ", map[i][j]); //2d表示每个字符占两位,使-1与0等齐
}
printf("\n");
}
}
然后就是埋雷的,因为是随机埋雷,所以需要用到随机函数rand();因此我们先在主函数中创建一个随机函数种子
srand((unsigned int)time(0));//生成随机数种子
然后就是用rand随机生成雷(-1),而且还要防止雷在同一个地方重复出现
//给数组随机埋雷,雷用-1表示,只要10个雷
for (int i = 0; i < 10;)
{
//雷的行列
int a = rand()%row;
int b = rand()%col;
if (map[a][b] == 0)//防止重复
{
map[a][b] = -1;
i++;//只有当-1赋值成功以后,才去遍历下一个雷
}
}
有了雷以后,就要对雷周围的数据进行修改,每个雷周围的九宫格都要在0的基础上加一 ,越界问题是扫雷的一个细节,要确保数据在界面以内
//雷周围的九宫格数字都加1,(雷自己除外)
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (map[i][j] == -1)
{
for (int a = i - 1; a <= i + 1; a++)
{
for (int b = j - 1; b <= j + 1; b++)
{
if ((a>=0&&a<row&&b>=0&&b<col)&&map[a][b] != -1)//防止越界且不能为雷
{
map[a][b]++;
}
}
}
}
}
}
基本数据已经搭建好了,接下来就是图形的绘制,我们可以在主函数上面先定义一个图形库窗口,且定义每一个图片大小为40
#define imagesize 40//定义图片大小
initgraph(row * imagesize, col * imagesize); //创建窗口
绘制图片分为三步:图片变量定义--图片加载--图片输出(图片如何输出问题在我之前的博客中有提及http://t.csdn.cn/PcJiP)
首先定义图片
IMAGE img[12];//定义图形










接着就是加载图片,这里为了方便,我运用了sprintf
void load()//加载图片
{
for (int i = 0; i < 12; i++)
{
//字符串格式化
char imagename[50];
sprintf(imagename, "./图片库/%d.jpg", i);
loadimage(img + i,imagename, imagesize, imagesize);
}
}
如果大家不了解sprintf,就可以使用常规方法,将图片逐一加载出来
void load()
{
loadimage(img + 0, "./图片库/0.jpg", imagesize, imagesize);
loadimage(img + 1, "./图片库/1.jpg", imagesize, imagesize);
loadimage(img + 2, "./图片库/2.jpg", imagesize, imagesize);
loadimage(img + 3, "./图片库/3.jpg", imagesize, imagesize);
loadimage(img + 4, "./图片库/4.jpg", imagesize, imagesize);
loadimage(img + 5, "./图片库/5.jpg", imagesize, imagesize);
loadimage(img + 6, "./图片库/6.jpg", imagesize, imagesize);
loadimage(img + 7, "./图片库/7.jpg", imagesize, imagesize);
loadimage(img + 8, "./图片库/8.jpg", imagesize, imagesize);
loadimage(img + 9, "./图片库/9.jpg", imagesize, imagesize);
loadimage(img + 10, "./图片库/10.jpg", imagesize, imagesize);
loadimage(img + 11, "./图片库/11.jpg", imagesize, imagesize);
}
接下来就是输出图片
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 * imagesize, i * imagesize, img + map[i][j]);
}
else if(map[i][j]==-1)//贴雷
{
putimage(j * imagesize, i * imagesize, img + 9);
}
}
}
这样我们的数据原型就做好了,接下来就是对其进行加密,也就是将雷和数字遮起来,我们这里的思路就是将每一个数字的结果加上date,然后使加上date后的数字对应改为第10号图形
#define date 20//定义date的值
//加密数据
for (int m = 0; m < row; m++)
{
for (int n = 0; n < col; n++)
{
map[m][n] += date;
}
}
然后就是对新的数字定义图形
//加密
if (map[i][j] >= -1 + date && map[i][j] <= 8 + date)
{
putimage(j * imagesize, i * imagesize, img + 10);
}
然后我们就需要通过鼠标点击对数据进行修改,我们定义鼠标每次点击后原数据减去date (对于鼠标如何操作,在我之前的博客中有提及http://t.csdn.cn/B7pwW)
if (MouseHit())//判断是否有鼠标操作
{
MOUSEMSG msg = GetMouseMsg();
//鼠标变量msg里面有x,y,但是没有行和列,需要自己求
int r = msg.y / imagesize;
int c = msg.x / imagesize;
//鼠标左键点击打开对应格子,让数组元素-date
if (msg.uMsg == WM_LBUTTONDOWN)
{
//避免越界
if (map[r][c] >= -1 + date && map[r][c] <=8 + date)
{
map[r][c] -= date;
gameover(r,c);
draw();//每次鼠标点完以后重新贴图
}
}}
插旗子也是如此
//右键按下插旗
if (msg.uMsg == WM_RBUTTONDOWN)
{
if (map[r][c] >= -1 + date && map[r][c] <= 8 + date)//标记
{
map[r][c] += date;
draw();//每次鼠标点完以后重新贴图
}
else if (map[r][c] > 8 + date)//再次点击取消标记
{
map[r][c] -= date;
draw();
}
然后就是输出旗子图片
else if(map[i][j]>8+date)
{
putimage(j * imagesize, i * imagesize, img + 11);
}
最后就是游戏结束的相关数据
void gameover(int x, int y)
{
//如果点到雷,就结束
if (map[x][y] == -1)
{
//打开所有的雷
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
//没标记的要打开
if (map[i][j] == -1 + date)
{
map[i][j] -= date;
}
//被标记的也要打开
else if (map[i][j] == -1 + date + date)
{
map[i][j] -= 2 * date;
}
}
}
draw();
//弹窗
int ret = MessageBox(GetHWnd(), "游戏结束", "提示", MB_OK);
if (ret == IDOK)
{
exit(0);//退出
}
}
}
将其汇总到主函数中即可
int main()
{
srand((unsigned int)time(0));//生成随机数种子
initgraph(row * imagesize, col * imagesize);
load();
initmap();
draw();
drawmap();
while (1)
{
mouse();
}
closegraph();
return 0;
}
总体代码就是这样,如果大家发现bug或者有更好的方法 ,欢迎大家一起来讨论呀,一起加油
#define _CRT_SECURE_NO_WARNINGS 1//忽略安全检测
#include<stdio.h>
#include<graphics.h>
#include<stdlib.h>
#include<time.h>
#define row 10//行
#define col 10//列
#define imagesize 40//定义图片大小
int map[row][col] = { 0 };//定义地图
#define date 20
IMAGE img[12];//定义图形
void drawmap()//绘制地图
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf(" %2d ", map[i][j]); //2d表示每个字符占两位
}
printf("\n");
}
}
//初始化数据
void initmap()
{
//给数组随机埋雷,雷用-1表示,只要10个雷
for (int i = 0; i < 10;)
{
//雷的行列
int a = rand()%row;
int b = rand()%col;
if (map[a][b] == 0)//防止重复
{
map[a][b] = -1;
i++;//只有当-1赋值成功以后,才去遍历下一个雷
}
}
//雷周围的九宫格数字都加1,(雷自己除外)
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (map[i][j] == -1)
{
for (int a = i - 1; a <= i + 1; a++)
{
for (int b = j - 1; b <= j + 1; b++)
{
if ((a>=0&&a<row&&b>=0&&b<col)&&map[a][b] != -1)//防止越界且不能为雷
{
map[a][b]++;
}
}
}
}
}
}
//加密数据
for (int m = 0; m < row; m++)
{
for (int n = 0; n < col; n++)
{
map[m][n] += date;
}
}
}
//void load()//加载图片
//{
// for (int i = 0; i < 12; i++)
// {
// //字符串格式化
// char imagename[50];
// sprintf(imagename, "./图片库/%d.jpg", i);
// loadimage(img + i,imagename, imagesize, imagesize);
// }
//}
void load()
{
loadimage(img + 0, "./图片库/0.jpg", imagesize, imagesize);
loadimage(img + 1, "./图片库/1.jpg", imagesize, imagesize);
loadimage(img + 2, "./图片库/2.jpg", imagesize, imagesize);
loadimage(img + 3, "./图片库/3.jpg", imagesize, imagesize);
loadimage(img + 4, "./图片库/4.jpg", imagesize, imagesize);
loadimage(img + 5, "./图片库/5.jpg", imagesize, imagesize);
loadimage(img + 6, "./图片库/6.jpg", imagesize, imagesize);
loadimage(img + 7, "./图片库/7.jpg", imagesize, imagesize);
loadimage(img + 8, "./图片库/8.jpg", imagesize, imagesize);
loadimage(img + 9, "./图片库/9.jpg", imagesize, imagesize);
loadimage(img + 10, "./图片库/10.jpg", imagesize, imagesize);
loadimage(img + 11, "./图片库/11.jpg", imagesize, imagesize);
}
//输出图片
void draw()
{
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 * imagesize, i * imagesize, img + map[i][j]);
}
else if(map[i][j]==-1)//贴雷
{
putimage(j * imagesize, i * imagesize, img + 9);
}
//加密
else if (map[i][j] >= -1 + date && map[i][j] <= 8 + date)
{
putimage(j * imagesize, i * imagesize, img + 10);
}
//插旗子
else if(map[i][j]>8+date)
{
putimage(j * imagesize, i * imagesize, img + 11);
}
}
}
}
//结束游戏
void gameover(int x, int y)
{
//如果点到雷,就结束
if (map[x][y] == -1)
{
//打开所有的雷
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
//没标记的要打开
if (map[i][j] == -1 + date)
{
map[i][j] -= date;
}
//被标记的也要打开
else if (map[i][j] == -1 + date + date)
{
map[i][j] -= 2 * date;
}
}
}
draw();
//弹窗
int ret = MessageBox(GetHWnd(), "游戏结束", "提示", MB_OK);
if (ret == IDOK)
{
exit(0);//退出
}
}
}
//鼠标操作
void mouse()
{
if (MouseHit())//判断是否有鼠标操作
{
MOUSEMSG msg = GetMouseMsg();
//鼠标变量msg里面有x,y,但是没有行和列,需要自己求
int r = msg.y / imagesize;
int c = msg.x / imagesize;
//鼠标左键点击打开对应格子,让数组元素-date
if (msg.uMsg == WM_LBUTTONDOWN)
{
//避免越界
if (map[r][c] >= -1 + date && map[r][c] <=8 + date)
{
map[r][c] -= date;
gameover(r,c);
draw();//每次鼠标点完以后重新贴图
}
}
//右键按下插旗
if (msg.uMsg == WM_RBUTTONDOWN)
{
if (map[r][c] >= -1 + date && map[r][c] <= 8 + date)//标记
{
map[r][c] += date;
draw();//每次鼠标点完以后重新贴图
}
else if (map[r][c] > 8 + date)//取消标记
{
map[r][c] -= date;
draw();
}
}
}
}
int main()
{
srand((unsigned int)time(0));//生成随机数种子
initgraph(row * imagesize, col * imagesize);
load();
initmap();
draw();
drawmap();
while (1)
{
mouse();
}
closegraph();
return 0;
}

1273

被折叠的 条评论
为什么被折叠?



