C语言easyX 实现推箱子图形界面小游戏 VC++6.0

这是基于EasyX图形库制作的一个简单的推箱子小游戏,只有一个地图,结构简单,适合初学EasyX图形库练手,下面是源码和一些贴图的构思

效果图:

在这里插入图片描述


贴图的原理:

(通过改变数组中图片对应的数字来达到移动贴图的效果)


地图数字对应的图片表示:

用 //0背景 //1墙 //2箱子 //3空地 //4人 //5目的地

对应图片资源:
在这里插入图片描述


1、人每走一步,就要贴一次人的图片,同时要改变人在mapIndex数组中对应的值:

图片对应改变情况:

  1. 空地—>人
  2. 人---->空地

2、每走一步时,对走的方向 进行判断

是否是箱子移动小人 同时 改变mapIndex地图中对应的值

如果人前面一格有箱子
图片变化情况:

  1. 箱子前的空地—>箱子,
  2. 箱子—>人
  3. 人—>空地

3、如果前面是墙,或者前面有两个箱子,则

退出此次循环,小人不移动,不贴图,不改值。


4、如果小人走是目的地,判断方法为:(通过判断该图片对应坐标),

判断小人现在的x,y坐标是否为目的地的坐标,是则画目的地的图:
步骤:

  1. 获取地图数组里数值为5的坐标,塞到用来存储目的地坐标的二维数组b[5][2]里;
  2. 判断小人当前坐标是否等于b数组中的x,y坐标,等于则只需要在小人走过的地方,贴目的地图片;
  3. 改变mapIndex地图数组中对应的值 注意:目的地,贴完目的地图后不需要进行赋值。

5、判断游戏结束

步骤

  1. 定义一个二维数组a[5][2],记录目的地坐标;
  2. 判断目的地坐标中值是否等于箱子的值2,如果全都等于2,则游戏结束,播放BGM提示游戏成功。

下面是源码:


/*///
//游戏中用//0背景//1墙//2箱子//3空地//4人//5目的地
//本程序由VC++6.0开发,采用了easyx函数库,请到http://www.easyx.cn/网站下载
//源码图片和文件可在https://download.csdn.net/download/weixin_43143173/10728154下载
///*/
#include<stdio.h>
#include<graphics.h>//图形库
#include<conio.h>
#include<mmsystem.h>//媒体音乐
#pragma comment(lib,"winmm.lib")

#define sizesImg 55//正方形图片的像素大小

//===============================地图一 ===============================-=
#define rows 7//行
#define cols 10//列
#define point 5//5个目的地
int pStartRow = 3;//小人初始的位置
int pStartCol = 8;//小人初始的位置

//0背景//1墙//2箱子//3空地//4人//5目的地

int map1[7][10] =
{
	0,0,0,1,1,1,1,1,1,0,
	0,1,1,1,3,3,3,3,1,0,
	1,1,5,3,2,1,1,3,1,1,
	1,5,5,2,3,2,3,3,4,1,
	1,5,5,3,2,3,2,3,1,1,
	1,1,1,1,1,1,3,3,1,0,
	0,0,0,0,0,1,1,1,1,0
};

/*

//==================================地图二 ===================================
#define rows 10//行
#define cols 12//列
int pStartRow=8;//小人初始的位置
int pStartCol=4;//小人初始的位置
#define point 5
//0背景//1墙//2箱子//3空地//4人//5目的地
*/
int map2[10][12] =
{
	0,0,0,0,0,0,0,0,1,1,1,1,
	0,0,0,0,0,0,1,1,1,3,3,1,
	1,1,1,1,1,1,1,3,3,3,3,1,
	1,3,3,3,2,3,3,3,3,3,3,1,
	1,3,3,3,2,1,1,1,3,1,1,1,
	1,1,1,5,2,5,5,5,3,5,1,0,
	0,0,1,3,2,1,3,3,3,3,1,0,
	0,0,1,3,2,3,1,1,1,1,1,0,
	0,0,1,3,4,3,1,0,0,0,0,0,
	0,0,1,1,1,1,1,0,0,0,0,0
};



IMAGE backimg;
IMAGE wall;
IMAGE box;
IMAGE grass;
IMAGE end;
IMAGE wpeople;
IMAGE apeople;
IMAGE speople;
IMAGE dpeople;


int rowNum = pStartRow, colNum = pStartCol;//地图一 小人的位置
int mapIndex2[rows][cols];
int endIndex[point][2] = { 0 }; //五个目的地点,定义一个目的地的数组下标
int endCoordinate[point][2] = { 0 };//五个目的地点,定义一个目的地的坐标数组

int x = colNum * sizesImg;//小人坐标
int y = rowNum * sizesImg;


void startGame(int(*mapIndex)[cols]);


//===============================加载图片============================================
void LoadImg()
{
	loadimage(&backimg, _T("IMAGE"), _T("background"), sizesImg, sizesImg);
	loadimage(&wall, _T("IMAGE"), _T("wall"), sizesImg, sizesImg);
	loadimage(&box, _T("IMAGE"), _T("box"), sizesImg, sizesImg);
	loadimage(&grass, _T("IMAGE"), _T("grass"), sizesImg, sizesImg);
	loadimage(&end, _T("IMAGE"), _T("end"), sizesImg, sizesImg);
	loadimage(&wpeople, _T("IMAGE"), _T("toppeople"), sizesImg, sizesImg);
	loadimage(&speople, _T("IMAGE"), _T("downpeople"), sizesImg, sizesImg);
	loadimage(&apeople, _T("IMAGE"), _T("leftpeople"), sizesImg, sizesImg);
	loadimage(&dpeople, _T("IMAGE"), _T("rightpeople"), sizesImg, sizesImg);
}


//0背景//1墙//2箱子//3空地//4人//5目的地

//===============================初始化游戏界面============================================
void InitGame(int(*mapIndex)[cols])
{
	LoadImg();

	for (int rowNum = 0; rowNum < rows; rowNum++)//绘制图片
	{
		for (int colNum = 0; colNum < cols; colNum++)
		{
			switch (mapIndex[rowNum][colNum])
			{
			case 0://背景
				putimage(colNum * sizesImg, rowNum * sizesImg, &backimg);
				break;
			case 1://墙壁
				putimage(colNum * sizesImg, rowNum * sizesImg, &wall);
				break;
			case 2://箱子
				putimage(colNum * sizesImg, rowNum * sizesImg, &box);
				break;
			case 3://空地
				putimage(colNum * sizesImg, rowNum * sizesImg, &grass);
				break;
			case 4://人物
				putimage(colNum * sizesImg, rowNum * sizesImg, &speople);
				break;
			case 5://目的地
				putimage(colNum * sizesImg, rowNum * sizesImg, &end);
				break;
			case 6:

			default:
				break;
			}
		}
	}
}

//============================重置界面Reset interface============================================
void resetGame(int(*mapIndex)[cols]) {
	memcpy(mapIndex, mapIndex2, sizeof(mapIndex2));
	rowNum = pStartRow;
	colNum = pStartCol;
	x = colNum * sizesImg;
	y = rowNum * sizesImg;
	InitGame(mapIndex);
}



//画目的地地图
void judge(int x, int y)//判断x,y是否属于目的地坐标
{
	//判断x,y是否满足在目的地的坐标,,,满足则画目的地的图
	for (int i = 0; i < point; i++) {
		if (x == endCoordinate[i][0] && y == endCoordinate[i][1]) {
			putimage(x, y, &end);//画目的地的图
			return;
		}
	}

	putimage(x, y, &grass);//画草
}




//==============================开始游戏===========================================
//Arrow keys to move around. Escape key to restart game

void playGame(int(*mapIndex)[cols])
{
	char input;//按键输入
	putimage(x, y, sizesImg, sizesImg, &speople, 0, 0);

	while (1)
	{
		//0背景//1墙//2箱子//3空地//4人//5目的地
		if (kbhit())//判断是否有输入//
		{
			input = getch();

			if (input == 's' || input == 80)//s键或下键//y变,坐标加
			{
				if (mapIndex[rowNum + 1][colNum] == 1 ||
					(mapIndex[rowNum + 2][colNum] == 2 && mapIndex[rowNum + 1][colNum] == 2) ||
					(mapIndex[rowNum + 2][colNum] == 1 && mapIndex[rowNum + 1][colNum] == 2)
					)
				{//人不动的三种情况:前面两个箱;前面箱子和墙;前面墙	
					continue;
				}
				else
				{//人箱都动的情况
					if (mapIndex[rowNum + 1][colNum] == 2)//else则都动,
					{
						putimage(x, y + sizesImg + sizesImg, &box);
						mapIndex[rowNum][colNum] = 3;//人变空地 ,数值4变3
						mapIndex[rowNum + 1][colNum] = 4;//箱变人 ,数值2变4
						mapIndex[rowNum + 2][colNum] = 2;//空地变箱 ,数值3变2		
						PlaySound(TEXT("res/箱子动.wav"), NULL, SND_SYNC | SND_FILENAME | SND_ASYNC);
					}
					else
					{//只有人动的情况
						mapIndex[rowNum + 1][colNum] = 4;//空地变人 ,数值3变4
						mapIndex[rowNum][colNum] = 3;//人变空地 ,数值4变3	
						PlaySound(TEXT("res/箭击中3.wav"), NULL, SND_SYNC | SND_FILENAME | SND_ASYNC);
					}
					putimage(x, y + sizesImg, &speople);
					judge(x, y);
					y = y + sizesImg;
					rowNum++;
				}
			}
//=========后面按键同s按键的方法=========//
			else if (input == 'w' || input == 72)//w键或上键//y变,减
			{
				if (mapIndex[rowNum - 1][colNum] == 1 ||
					(mapIndex[rowNum - 2][colNum] == 2 && mapIndex[rowNum - 1][colNum] == 2) ||
					(mapIndex[rowNum - 2][colNum] == 1 && mapIndex[rowNum - 1][colNum] == 2)
					)//人箱不动
				{
					continue;
				}
				//人箱移动
				else
				{
					if (mapIndex[rowNum - 1][colNum] == 2)//人箱都动
					{
						putimage(x, y - sizesImg - sizesImg, &box);
						mapIndex[rowNum][colNum] = 3;//人变空地 4变3
						mapIndex[rowNum - 1][colNum] = 4;//箱变人 2变4
						mapIndex[rowNum - 2][colNum] = 2;//空地变箱 3变2
						PlaySound(TEXT("res/箱子动.wav"), NULL, SND_SYNC | SND_FILENAME | SND_ASYNC);
					}
					else//人动
					{
						mapIndex[rowNum][colNum] = 3;//人变空地 4变3
						mapIndex[rowNum - 1][colNum] = 4;//空地变人 3变4
						PlaySound(TEXT("res/箭击中3.wav"), NULL, SND_SYNC | SND_FILENAME | SND_ASYNC);
					}
					putimage(x, y - sizesImg, &wpeople);

					judge(x, y);
					y = y - sizesImg;
					rowNum--;
				}
			}

			else if (input == 'a' || input == 75)//a键或左键//x变,坐标减
			{
				if (mapIndex[rowNum][colNum - 1] == 1 ||
					(mapIndex[rowNum][colNum - 2] == 2 && mapIndex[rowNum][colNum - 1] == 2) ||
					(mapIndex[rowNum][colNum - 2] == 1 && mapIndex[rowNum][colNum - 1] == 2)
					)//人箱不动
				{
					continue;
				}
				else
				{
					if (mapIndex[rowNum][colNum - 1] == 2)//人箱都动
					{
						putimage(x - sizesImg - sizesImg, y, &box);//画箱子						
						mapIndex[rowNum][colNum - 2] = 2;
						mapIndex[rowNum][colNum - 1] = 4;
						mapIndex[rowNum][colNum] = 3;
						PlaySound(TEXT("res/箱子动.wav"), NULL, SND_SYNC | SND_FILENAME | SND_ASYNC);
					}
					else //人动
					{
						mapIndex[rowNum][colNum] = 3;
						mapIndex[rowNum][colNum - 1] = 4;
						PlaySound(TEXT("res/箭击中3.wav"), NULL, SND_SYNC | SND_FILENAME | SND_ASYNC);
					}
					putimage(x - sizesImg, y, &apeople);//画人					
					judge(x, y);

					x = x - sizesImg;
					colNum--;//x值减1	
				}
			}

			else if (input == 'd' || input == 77)//d键或右键//x变,坐标加
			{
				if (mapIndex[rowNum][colNum + 1] == 1 || (mapIndex[rowNum][colNum + 2] == 2 && mapIndex[rowNum][colNum + 1] == 2) ||
					(mapIndex[rowNum][colNum + 2] == 1 && mapIndex[rowNum][colNum + 1] == 2)
					)//人箱不动
				{
					continue;
				}
				else//人箱移动
				{
					if (mapIndex[rowNum][colNum + 1] == 2)
					{
						putimage(x + sizesImg + sizesImg, y, &box);//画箱子					
						mapIndex[rowNum][colNum + 2] = 2;
						mapIndex[rowNum][colNum + 1] = 4;
						mapIndex[rowNum][colNum] = 3;
						PlaySound(TEXT("res/箱子动.wav"), NULL, SND_SYNC | SND_FILENAME | SND_ASYNC);
					}
					else
					{
						mapIndex[rowNum][colNum] = 3;
						mapIndex[rowNum][colNum + 1] = 4;
						PlaySound(TEXT("res/箭击中3.wav"), NULL, SND_SYNC | SND_FILENAME | SND_ASYNC);
					}
					putimage(x + sizesImg, y, &dpeople);//画人					
					judge(x, y);
					x = x + sizesImg;//移动的坐标		
					colNum++;
				}
			}
			else if (input == 27)//按Esc重置游戏
			{
				resetGame(mapIndex);
			}

			if (mapIndex[endIndex[0][0]][endIndex[0][1]] == 2 &&
				mapIndex[endIndex[1][0]][endIndex[1][1]] == 2 && mapIndex[endIndex[2][0]][endIndex[2][1]] == 2 &&
				mapIndex[endIndex[3][0]][endIndex[3][1]] == 2 && mapIndex[endIndex[4][0]][endIndex[4][1]] == 2
				)//五个目的地 图片对应的值全部为2时,游戏结束
			{
				PlaySound("res/欢呼.wav", NULL, SND_SYNC | SND_FILENAME | SND_ASYNC);
				return;
			}
		}
	}
}


void InitCoordinate(int(*mapIndex)[cols]) {//初始化各图片的x,y坐标
	int i = 0;
	for (int rowNum = 0; rowNum < rows; rowNum++)//作用,把目的地的坐标x,y复制给b的二维数组
	{
		for (int colNum = 0; colNum < cols; colNum++)
		{
			if (mapIndex[rowNum][colNum] == 5)
			{
				endCoordinate[i][0] = colNum * sizesImg;
				endCoordinate[i][1] = rowNum * sizesImg;
				endIndex[i][0] = rowNum;
				endIndex[i][1] = colNum;
				i++;
			}
		}
	}
}


void startGame(int(*mapIndex)[cols]) {

	initgraph(cols*sizesImg, rows*sizesImg, 0);//初始化画布

	InitCoordinate(mapIndex);//记录贴图的x,y坐标

	InitGame(mapIndex);//初始化游戏界面//Initialize game interface

	playGame(mapIndex);//开始游戏
}


int main()
{
	memcpy(mapIndex2, map1, sizeof(map1));//保存初始地图//Save initial map

	startGame(map1);//开始游戏

	getch();

	closegraph();//关闭画布

	return 0;
}


  • 20
    点赞
  • 129
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值