c语言实现推箱子小游戏

C语言 专栏收录该内容
4 篇文章 0 订阅

c语言实现推箱子小游戏

先让大家看一下效果

在这里插入图片描述
在这里插入图片描述

下面是实现推箱子小游戏的全部代码

这个推箱子小游戏采用文件操作,通过easy_x图形库实现了图形界面,相对来说更具有玩游戏的感觉,给人以视觉盛宴。

说笑了,好了大家可以好好的看一下源代码
本游戏所需的关卡文件在最后面,大家可以看一下
另外运行此小游戏,大家可能还需要安装easy_x图形库文件,这里我分享以下easy_x的安装文件链接,由于时间关系,本游戏只设计了三关,在闯关成功后,可以弹出闯关成功的提示

链接:https://pan.baidu.com/s/1zvMlFfLkKtU0sIwSS2KU2g
提取码:q3n8

关于本游戏的resource.h ,这个是需要我们导入图片后,才会有的头文件,下面是关于本游戏的图片素材,我会演示一下VS 如何导入图片

链接:https://pan.baidu.com/s/1arc-bL-x6GG3Yrtfb70GeQ
提取码:4xx5
上面的图片链接已失效,我重新发了一份在下面
链接:https://pan.baidu.com/s/1iiyBzp04YQ_bhycJOAx6dw
提取码:4n4n
复制这段内容后打开百度网盘手机App,操作更方便哦
上面是图片素材的百度网盘链接
下面是VS 导入图片的具体方法:
在这里插入图片描述
右键资源文件 选择添加->资源
然后,出现在这里插入图片描述
选择 Bitmap(位图),选择导入,找到你图片素材的存储路径,
在这里插入图片描述
这时你会发现素材路径下什么都没有,别急,我们需要把上面图片中的位图换成
在这里插入图片描述
就会出现图片素材了,全部选中,点击打开,
然后就会出现 resource.h这个头文件了

1.推箱子总体概述

1.1游戏总体设计

此游戏本着娱乐为目的,游戏界面简单,操作容易,游戏者可以在游戏中锻炼反应速度与灵敏速度,在游戏中设置有关卡,级别由低到高,一关更比一关难。

1.2功能模块规划

在该游戏中共设计了三个模块:

(1)初始化模块,

对游戏界面进行初始化,包含两个函数,分别为GameInitMap函数,进行图片的加载,GamePaint,进行贴图,从而完成对地图的绘制,在此游戏中,不同的数字代表贴不同的图。

(2)游戏操作模块,

由GamePlay构成玩家通过对小人的操作使小人能够操作木箱到各个位置

(3)游戏判断模块,

由GameJudgement构成,通过对地图的遍历,观察是否有箱子未推到目的地,进行游戏是否结束的判断。

2程序说明

2.1 按钮设计

游戏中通过键盘输入来操作小人移动箱子完成游戏任务,键盘输入按钮及其效果如下
(1)上:通过按w或W或 来移动小人往上移动。
(1)下:通过按s或S或 来移动小人往下移动。
(1)左:通过按a或A或 来移动小人往左移动。
(1)右:通过按d或D或 来移动小人往右移动。

2.2地图的绘制形成—初始化模块

(1)二维数组数字的意义
 地图是以二维数组的形式进行存储的,不同的数字有着不同的含义。我将0~9解读为不同的图形。
 0代表地图内的空位;
 1代表墙壁;
 3’代表目的地;
 4代表箱子;
 5代表小人;
 7代表箱子在目的地;
 8代表人在目的地。
(2)加载图片与贴图

本游戏地图的绘制采用Easyx library进行游戏界面的加载与绘制,先声明IMAGE变量, loadimage函数用来进行图片的加载,然后用文件操作,从Map.txt读取地图信息,通过双层循环进行遍历,根据对应位置的Map二维数组的值来选择不同的图片进行贴图。

2.3游戏操作模块

2.3.1关卡设计

本游戏采用文件操作进行关卡的设计,地图信息存储在Map.txt文档中,当一个关卡通过判断通过时,地图通过文件操作进行更新,直到所有关卡完成,弹出闯关成功窗口。
关卡设计

2.3.2小人与箱子移动

本游戏移动只有正移动,小人上下移动归结起来是一个判断的算法。判断都是通过小人前面是否是空位,箱子,或者是墙。如果没有,就移动;有的话,在判断箱子是否可以移动。最后讨论箱子推过的,小移动的图形变化,重新绘制地图。:

2.4游戏判断模块

游戏通过双层for循环进行地图遍历,观察地图上是否有没有推到目的地的箱子,并返回结果,从而对这一关游戏与游戏是否结束进行判断,全部代码如下:

#include <stdio.h>
#include <conio.h> //控制台输入输出的头文件
#include <graphics.h> //头文件图形库
#include "resource.h"
int Map[8][8] = {
0, 0, 0, 1, 1, 1, 0, 0,
0, 0, 0, 1, 3, 1, 0, 0,
1, 1, 1, 1, 0, 1, 0, 0,
1, 3, 4, 0, 4, 1, 1, 1,
1, 1, 1, 5, 4, 0, 3, 1,
0, 0, 1, 4, 1, 1, 1, 1,
0, 0, 1, 3, 1, 0, 0, 0,
0, 0, 1, 1, 1, 0, 0, 0
};
void GameInitMap();//加载图片
void GamePaint(); //贴图
void GamePlay(); //操作
int GameJudgement(); //判断游戏是否结束
IMAGE BackImage, Wall;  //背景  墙
IMAGE Box, dBox; //箱子 箱子推到目的地
IMAGE Point; //目的地
IMAGE Person; //人
void GameInitMap(int live) //给出关卡数 用来判断是第几关
{	
loadimage(&BackImage, L"jpg",MAKEINTRESOURCE(101), 550, 550);//背景
loadimage(&Wall, L"jpg", MAKEINTRESOURCE(107), 69, 69);//墙壁
loadimage(&Box, L"jpg", MAKEINTRESOURCE(103), 69, 69);//箱子
loadimage(&Point, L"jpg", MAKEINTRESOURCE(106), 69, 69);//目的地
loadimage(&dBox, L"jpg", MAKEINTRESOURCE(104), 69, 69);//箱子到达目的地
loadimage(&Person, L"jpg", MAKEINTRESOURCE(105), 69, 69);//人物
FILE *fp = fopen("Map.txt", "r");
if (NULL == fp)  //如果打开失败  异常处理
{
	MessageBox(NULL, L"地图加载失败", NULL, NULL);
	exit(0);
}
int FileOffset; // 文件的偏移
FileOffset = 66 * (live - 1);
fseek(fp, FileOffset, SEEK_SET);
int i, j;
char c;
for (i = 0; i < 8; i++)
{
	for (j = 0; j < 8; j++)
	{
		c = fgetc(fp);
		Map[i][j] = c - '0';
	}
}
fclose(fp); //关闭文件  
}
void GamePaint()
{
for (int i = 0; i < 8; ++i)
{
	for (int j = 0; j < 8; ++j)
	{
		switch (Map[j][i])
		{
		case 0: //空地
			break;
		case 1: //墙壁
			putimage(69 * i, 69 * j, &Wall);
			break;
		case 3://目的地
			putimage(69 * i, 69 * j, &Point);
			break;
		case 4://箱子
			putimage(69 * i, 69 * j, &Box);
			break;
		case 5://人物
			putimage(69 * i, 69 * j, &Person);
			break;
		case 7://箱子在目的地上
			putimage(69 * i, 69 * j, &dBox);
			break;
		case 8://人物在目的地上
			putimage(69 * i, 69 * j, &Person);
			break;
		}
	}
}
}
/*
0       空地
1       墙壁
3       目的地
4       箱子
5       人物
7       箱子在目的地
8       人在目的
*/
int GameJudgement()
{
for (int i = 0; i < 8; i++)
{
	for (int j = 0; j < 8; j++)
	{
		if (Map[i][j] == 4) //判断 有没有落在空地上的箱子
		{
			return 1;  //游戏还没有结束
		}
	}
}
return 0;
}

void GamePlay()
{
	char ch; //用来获取键盘输入的信息
	int x, y; //描述当前坐标
	int live = 1; //描述关卡
	GameInitMap(live); //贴图
	while (true)
	{
		BeginBatchDraw();
		cleardevice();
		putimage(0, 0, &BackImage);
		if (!GameJudgement()) //判断 每一关是否玩完了
		{
			live++;  // 进入下一关
			if (4 == live) //
			{
				GamePaint();// 绘图
				FlushBatchDraw(); //批量绘图 防闪屏
				MessageBox(GetHWnd(), L"闯关成功\r\n", L"闯关提示", MB_OK);
				// 弹出对话框 
				FlushBatchDraw();
				Sleep(5000); 
				closegraph(); //关闭窗口
				exit(0); //结束程序
			}
			GameInitMap(live);
		} 
		//批量绘图结束
		GamePaint();
		EndBatchDraw();
		for (x = 0; x < 8; x++)
		{
			for (y = 0; y < 8; y++)
			{	//如果人在目的地 或者 人在空地
				if (Map[x][y] == 5 || Map[x][y] == 8)
				{
					break;
				}
			}
			if (Map[x][y] == 5 || Map[x][y] == 8)
			{
				break;
			}
		}
		ch = getch(); //获取键盘消息
		//人在 Map[x][y]
		switch (ch)
		{
		case 'w': 
		case 'W':
		case 72://向上
			if (Map[x - 1][y] == 0 || Map[x - 1][y] == 3)
			{
				Map[x][y] -= 5; 
				Map[x - 1][y] += 5; 
			}
			else if (Map[x - 1][y] == 4 || Map[x - 1][y] == 7)
			{
				if (Map[x - 2][y] == 0 || Map[x - 2][y] == 3)
				{
					Map[x - 2][y] += 4;
					Map[x - 1][y] += 1;
					Map[x][y] -= 5; 
				}
			}
			break;
		case 'a':
		case 'A':
		case 75://向左
			if (Map[x][y - 1] == 0 || Map[x][y - 1] == 3)
			{
				Map[x][y] -= 5;
				Map[x][y - 1] += 5;
			}
			else if (Map[x][y - 1] == 4 || Map[x][y - 1] == 7)
			{
				if (Map[x][y - 2] == 0 || Map[x][y - 2] == 3)
				{
					Map[x][y - 2] += 4;
					Map[x][y - 1] += 1;
					Map[x][y] -= 5;
				}
			}
			break;
		case 's':
		case 'S':
		case 80:  // 往下
			if (Map[x + 1][y] == 0 || Map[x + 1][y] == 3)
			{
				Map[x][y] -= 5;
				Map[x + 1][y] += 5;
			}
			else if (Map[x + 1][y] == 4 || Map[x + 1][y] == 7)
			{
				if (Map[x + 2][y] == 0 || Map[x + 2][y] == 3)
				{
					Map[x + 2][y] += 4;
					Map[x + 1][y] += 1;
					Map[x][y] -= 5;
				}
			}
			break;
		case 'd':
		case 'D':
		case 77:  //往右
			if (Map[x][y + 1] == 0 || Map[x][y + 1] == 3)
			{
				Map[x][y] -= 5;
				Map[x][y + 1] += 5;
			}
			else if (Map[x][y + 1] == 4 || Map[x][y + 1] == 7)
			{
				if (Map[x][y + 2] == 0 || Map[x][y + 2] == 3)
				{
					Map[x][y + 2] += 4;
					Map[x][y + 1] += 1;
					Map[x][y] -= 5;
				}
			}
			break;
		}
	}
}
int main()
{
	initgraph(550, 550);
	GamePlay();
	return 0;
}

关卡文件的配置
请在项目文件下建立 “地图Map.txt"文件,并将下面内容复制进去

	0001110000013100111101001340411111154031001411110013100000111000
	0111111101000001010343011104540110034301100000011111111100000000
	0111100001001000010310001145100010401111100300011111000100011111
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

Sundm@lhq

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值