欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-07 17:22:57
...

写在前面

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

easyx库

点击这里下载如下图,点击右上角黄色区域下载。
用C语言easyx库来写一个简单的翻翻乐小游戏(附源码素材)
安装:如下图,安装对应版本即可
用C语言easyx库来写一个简单的翻翻乐小游戏(附源码素材)

准备工作

新建项目文件

新建文件的时候要注意,文件后缀使用.cpp而不是.c,因为easyx库的一些东西使用了C++,所以这样最为保险。
用C语言easyx库来写一个简单的翻翻乐小游戏(附源码素材)

分析

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

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

素材分析

事实上,这个游戏的实现就是通过调用不同的图片来实现的。我收集了一些图片:
用C语言easyx库来写一个简单的翻翻乐小游戏(附源码素材)

上代码吧

地图表示

#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");
}

测试

用C语言easyx库来写一个简单的翻翻乐小游戏(附源码素材)
主界面大概就是这样,下面看看游戏界面,勉强凑活吧(太丑了)………………
用C语言easyx库来写一个简单的翻翻乐小游戏(附源码素材)

优化

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

1、游戏分数

游戏的计分方式没有设定,我就暂时先设定一下,
我的规则是下面这样:用C语言easyx库来写一个简单的翻翻乐小游戏(附源码素材)
补充一点,游戏最低分为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)
			…………………………………………

效果展示

游戏效果展示

待优化部分

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

源码和素材

我放在微信公众号后台了。
用C语言easyx库来写一个简单的翻翻乐小游戏(附源码素材)

点击获取…………

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