用C语言easyx库来写一个简单的翻翻乐小游戏(附源码素材)

写在前面

所用素材若有侵权,联系我删除。
素材和源码在文末
另外,其实这是从我的一个大一点的项目中摘取出来的,尽管有所修改,但是难免有些问题,而且代码非常繁琐,没有简化,注释也写的不够全面……

easyx库

点击这里下载如下图,点击右上角黄色区域下载。
在这里插入图片描述
安装:如下图,安装对应版本即可
在这里插入图片描述

准备工作

新建项目文件

新建文件的时候要注意,文件后缀使用.cpp而不是.c,因为easyx库的一些东西使用了C++,所以这样最为保险。
在这里插入图片描述

分析

我们先进行一定的分析,理一下思路。

void main()
{
//主函数
}
void set_map()
{
//地图的初始化
}
int play()
{
//游戏过程
}
int begin_menu()
{
//开始界面
}
int game_over()
{
//结束界面
}

素材分析

事实上,这个游戏的实现就是通过调用不同的图片来实现的。我收集了一些图片:
在这里插入图片描述

上代码吧

地图表示

#include <graphics.h>//引用easyx库
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
int map[6][6] = {{1,1,1,1,2,2},{2,2,5,5,2,2},{3,3,3,3,4,4},{5,5,6,6,6,6},{7,7,1,1,7,7},{8,8,4,4,8,8} };

我们用数组来表示地图内容,数字分别代表图片。

开始界面

int begin_menu()
{
	initgraph(1152, 648);//界面绘制
	IMAGE menu;//开始菜单图片
	loadimage(&menu, _T("begin_menu0.jpg"), 1152, 648);
	IMAGE shuoming;//游戏说明
	loadimage(&shuoming, _T("begin_menu01.jpg"), 1152, 648);
	putimage(0, 0, &menu);

	MOUSEMSG mouse;
	MOUSEMSG mouse2;
	int x2, y2;
	int x, y;
	while (1)
	{
		mouse = GetMouseMsg();
		if (mouse.uMsg == WM_LBUTTONDOWN)//左键按下
		{
			x = mouse.x;
			y = mouse.y;//鼠标坐标
			if (x <= 635 && x >= 461 && y >= 185 && y <= 238)//开始游戏
			{
				break;
			}
			else if (x <= 635 && x >= 461 && y >= 281 && y <= 330)//说明
			{
				cleardevice;
				putimage(0, 0, &shuoming);
				while (1)
				{
					mouse2 = GetMouseMsg();
					if (mouse2.uMsg == WM_LBUTTONDOWN)
					{
						mouse2 = GetMouseMsg();
						x2 = mouse2.x;
						y2 = mouse2.y;
						if (x2 <= 228 && x2 >= 52 && y2 >= 15 && y2 <= 65)//返回
						{
							putimage(0, 0, &menu);
							break;
						}
					}
					Sleep(10);
				}
				continue;
			}
		}
		Sleep(10);
	}
	return 0;
	closegraph();
}

地图初始化(打乱)

void set_maps()
{
	initgraph(800, 600);
	setlinecolor(WHITE);
	setfillcolor(BLACK);
	fillrectangle(602, 1, 799, 599);
	srand((unsigned int)time(NULL));//随机数种子
	for (int a = 0; a < 5; a++)//反复打乱
	{
		for (int x = 0; x < 6; x++)
		{
			for (int y = 0; y < 6; y++)
			{
				int suijishu = rand() % 100;//产生随机数
				if (x == 0 && y == 0)
				{
					if (suijishu > 50)
					{
						chang_one(x, y, RIGHT)//和右边数字交换
					}
					else
					{
						chang_one(x, y, DOWN);
					}
				}
			//………………此处省略很多行
			}
		}
	}
}

因为涉及到边角等块的情况不同,所以我分类很多,而且用了随机数来增加随机性,所以分类就更多了。这里为了数字交换方便起见,我定义了一个change_one函数,用于交换两个数字。

void chang_one(int x, int y, int direction)
{
	int t;
	if (direction == RIGHT)
	{
		t = map[x][y];
		map[x][y] = map[x][y + 1];
		map[x][y + 1] = t;
	}
	else if (direction == DOWN)
	{
		t = map[x][y];
		map[x][y] = map[x + 1][y];
		map[x + 1][y] = t;
	}
	else if (direction == LEFT)
	{
		t = map[x][y];
		map[x][y] = map[x][y - 1];
		map[x][y - 1] = t;
	}
	else if (direction == UP)
	{
		t = map[x][y];
		map[x][y] = map[x - 1][y];
		map[x - 1][y] = t;
	}
}

游戏过程实现

int plays()
{
	IMAGE imgs[10];//不同的图片
	loadimage(&imgs[0], _T("0.jpg"), 100, 100);
	loadimage(&imgs[1], _T("1.jpg"), 100, 100);
	loadimage(&imgs[2], _T("2.jpg"), 100, 100);
	loadimage(&imgs[3], _T("3.jpg"), 100, 100);
	loadimage(&imgs[4], _T("4.jpg"), 100, 100);
	loadimage(&imgs[5], _T("5.jpg"), 100, 100);
	loadimage(&imgs[6], _T("6.jpg"), 100, 100);
	loadimage(&imgs[7], _T("7.jpg"), 100, 100);
	loadimage(&imgs[8], _T("8.jpg"), 100, 100);
	loadimage(&imgs[9], _T("yuanshi.jpg"), 100, 100);//背景图
	for (int x = 0; x < 6; x++)
	{
		for (int y = 0; y < 6; y++)
		{
			putimage(100 * y, 100 * x, &imgs[0]);//先放满背景图
			Sleep(25);
		}
	}
	MOUSEMSG mouse;
	int x, y;//鼠标数组下标
	int times = 0;
	int t, x0 = -1, y0 = -1;
	number_write(30, 650, 350, 0, WHITE);///自己定义的函数。用于书写数字
	while (1)
	{
		mouse = GetMouseMsg();
		if (mouse.uMsg == WM_LBUTTONDOWN)
		{
			x = mouse.y / 100;
			y = mouse.x / 100;
			if (map[x][y] != 0 && mouse.x < 600)//防止点击到右边界面
			{
				if (((x0 != x) | (y0 != y)))//保证两次点击的不是同一张图片
				{
					times++;
					putimage(100 * y, 100 * x, &imgs[map[x][y]]);
				}
				if (times % 2 == 0)
				{
					if (map[x][y] != t)
					{
						Sleep(100);
						putimage(100 * y0, 100 * x0, &imgs[0]);
						putimage(100 * y, 100 * x, &imgs[0]);
						t = -1;
						x0 = -1;
						y0 = -1;
					}
					else if (map[x][y] == t && ((x0 != x) | (y0 != y)))
					{
						Sleep(100);
						putimage(100 * y0, 100 * x0, &imgs[9]);
						putimage(100 * y, 100 * x, &imgs[9]);
						map[x][y] = 0;
						map[x0][y0] = 0;
						jishuqi += 2;
					}
				}
				else if (times % 2 == 1 && ((x0 != x) | (y0 != y)))
				{
					t = map[x][y];//记录上一次点击的数字
					x0 = x;
					y0 = y;
				}
			}
		}
		Sleep(2);
		if (jishuqi == 36)//成功检测
			return SUCCESS;
	}
}

主函数的实现

void main()
{
	begin:begin_menu();
	set_maps();
	int result = plays();
	int choice = game_over(result);
	if (choice == 1)
	{
		closegraph();
		initgraph(1152, 648);
		goto begin;
	}
	system("pause");
}

测试

在这里插入图片描述
主界面大概就是这样,下面看看游戏界面,勉强凑活吧(太丑了)………………
在这里插入图片描述

优化

其实,上面的过程中有很多的问题没有解决,下面优化一部分:

1、游戏分数

游戏的计分方式没有设定,我就暂时先设定一下,
我的规则是下面这样:在这里插入图片描述
补充一点,游戏最低分为0分。

2、游戏时间

我认为游戏应该是随时显示时间,并且不能无限玩下去吧??我就暂时先设置成60s吧……

3、number_write函数没有给出

void number_write(int number_size, int x, int y, int number, COLORREF color)
{
	TCHAR s[30];
	_stprintf_s(s, _T("%d"), number);//需要先把数字进行转换
	settextstyle(number_size, 0, _T("黑体"));
	settextcolor(color);
	outtextxy(x, y, s);
}

4、游戏结束函数

int game_over(int result)//1返回,0下一关
{
	IMAGE over[2];
	loadimage(&over[0], _T("success.jpg"), 500, 350);
	loadimage(&over[1], _T("failed.jpg"), 500, 350);
	if (result == 1)//游戏成功
	{
		putimage(50, 125, &over[0]);
		MOUSEMSG mouse;
		int x, y;
		while (1)
		{
			mouse = GetMouseMsg();
			if (mouse.uMsg == WM_LBUTTONDOWN)
			{
				x = mouse.x;
				y = mouse.y;

				if (x >= 200 && x <= 304 && y >= 248 && y <= 286)//返回
				{
					return 1;
				}
				else if (x >= 383 && x <= 486 && y >= 248 && y <= 286)//下一关
				{
					return 0;
				}
			}
			Sleep(10);
		}
	}
	else//失败
	{
		putimage(50, 125, &over[1]);
		MOUSEMSG mouse1;
		int x1, y1;
		while (1)
		{
			mouse1 = GetMouseMsg();
			if (mouse1.uMsg == WM_LBUTTONDOWN)
			{
				x1 = mouse1.x;
				y1 = mouse1.y;
				if (x1 >= 204 && x1 <= 412 && y1 >= 340 && y1 <= 405)//返回
				{
					return 1;
				}
			}
			Sleep(10);
		}
	}
}

5、游戏下一关的设定

这一块由于时间仓促,暂时还没有给出………………

6、游戏重新进入

这里有一个问题,如果退出以后,其实数组的值就已经改变了,,再次开始以后,不能初始化了??
这里,我们做一个修改

int map1[6][6] = { {1,1,1,1,2,2},{2,2,5,5,2,2},{3,3,3,3,4,4},{5,5,6,6,6,6},{7,7,1,1,7,7},{8,8,4,4,8,8} };
//定义一个数组来记录原来数组的值

void main()
{
	……
	if (choice == 1)
	{
		closegraph();
		initgraph(1152, 648);
		for (int x = 0; x < 6; x++)
		{
			for (int y = 0; y < 6; y++)
			{
				map[x][y] = map1[x][y];//数组值初始化
			}
		}
		goto begin;
	}
	system("pause");
}

7、分数显示

其实这里有一个问题。文伟我的分数模式会导致分数上升以后还有下降可能,所以会有问题。
比如,我的分数是10分,但是后来又变成了9分,由于分数书写时覆盖原来数字的,所以,9(一位数)不能完全覆盖10(两位数),所以,就会呈现出90分的样子……
所以,我的解决方法是用黑图片覆盖原来分数……

8、返回优化

如果游戏中想要返回呢?我就增加一个返回按钮吧。

******************初始化函数的一点修改
IMAGE back;
loadimage(&back, _T("back.jpg"), 160, 50);
putimage(620, 500, &back);
……………………^…………^……
……………………………………主函数一点修改
if (mouse.x >= 620 && mouse.x <= 780 && mouse.y >= 500 && mouse.y <= 550)
			{
				return FAIL;
			}
			else if (map[x][y] != 0 && mouse.x < 600)
			…………………………………………

效果展示

[video(video-b7mY7LSX-1586435967267)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=540220179)(image-https://ss.csdn.net/p?http://i1.hdslb.com/bfs/archive/31c99aafc885d0a09f192c2f1ba03e9b16c7492c.jpg)(title-翻翻乐游戏效果展示)]

待优化部分

1、下一关的问题,大家自行解决吧,也不难……
2、背景音乐的问题,虽然这个不难,但是没找到合适的素材,大家自己解决吧。
3、重点问题,
时间的问题,因为循环中,如果你的鼠标没有动作,那么程序就停在那里了????这咋办??

源码和素材

我放在微信公众号后台了。
在这里插入图片描述

点击获取…………

在这里插入图片描述

发布了4 篇原创文章 · 获赞 8 · 访问量 461

猜你喜欢

转载自blog.csdn.net/weixin_46283214/article/details/105413535
今日推荐