c语言小游戏--扫雷

  (创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)

今天我们来尝试用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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小周不想卷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值