EasyX实现推箱子游戏

1 项目需求

实现一款推箱子游戏,效果如下图所示,具体规则:

  1. 箱子只能推动而不能拉动;
  2. 如果箱子前一格是地板或箱子目的地,则可以推动一个箱子往前走一格,如果箱子已经在箱子目的地则不能再推动;
  3. 推箱子的小人不能从箱子目的地上直接穿过;
  4. 注意不要把箱子推到死角上,不然就无法再推动它了;
  5. 所有箱子都成功推到箱子目的地,游戏结束,过关成功!
    在这里插入图片描述

2 模块划分

作用:

  1. 化繁为简 。
  2. 适合团队协作。
  3. 高质量代码。

在这里插入图片描述


3 项目实现

3.1 地图初始化

搭台唱戏: 戏台坐标系(650 x 650)。
在这里插入图片描述

地图表示: 使用二维数组 。

  • 游戏道具显示(墙、箱子、箱子目的地、小人、地板)。
  • 便于程序在游戏过程中进行逻辑判断和控制小人向前一步的动作控制。
  • 判断游戏结果。

道具表示:

  • 墙:0
  • 地板:1
  • 箱子目的地:2
  • 小人:3
  • 箱子:4
  • 箱子命中目标:5

在这里插入图片描述

#include <graphics.h> 
#include <iostream> 
#include <stdlib.h> 
#include <string> 

using namespace std; 

#define RATIO 61 

#define SCREEN_WIDTH 960 
#define SCREEN_HEIGHT 768 

#define LINE 9 
#define COLUMN 12 

#define START_X 100 
#define START_Y 150 

IMAGE images[6]; 

/*游戏地图*/ 
int map[LINE][COLUMN] = { 
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
	{ 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
	{ 0, 1, 4, 1, 0, 2, 1, 0, 2, 1, 0, 0 },
	{ 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0 },
	{ 0, 1, 0, 2, 0, 1, 1, 4, 1, 1, 1, 0 },
	{ 0, 1, 1, 1, 0, 3, 1, 1, 1, 4, 1, 0 },
	{ 0, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 0 },
	{ 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}; 

int main(void) {
	IMAGE bg_img; //搭台唱戏 
	
	initgraph(SCREEN_WIDTH, SCREEN_HEIGHT); 
	loadimage(&bg_img, _T("blackground.bmp"), SCREEN_WIDTH, SCREEN_HEIGHT, true); 
	putimage(0, 0, &bg_img); //加载道具图标 

	loadimage(&images[0], _T("wall.bmp"), RATIO, RATIO, true); 
	loadimage(&images[1], _T("floor.bmp"), RATIO, RATIO, true); 
	loadimage(&images[2], _T("des.bmp"), RATIO, RATIO, true); 
	loadimage(&images[3], _T("man.bmp"), RATIO, RATIO, true); 
	loadimage(&images[4], _T("box.bmp"), RATIO, RATIO, true); 
	loadimage(&images[5], _T("box.bmp"), RATIO, RATIO, true); 
	
	for(int i = 0; i< LINE; i++){ 
		for(int j = 0; j < COLUMN; j++){ 
			putimage(START_X+j*RATIO, START_Y+i*RATIO, &images[map[i][j]]); 
		} 
	}
	
	system("pause"); 
	
	return 0; 
}

3.2 热键控制

热键定义: 左 => a 下=> s 上=> w 右 => d 退出 => q。

#include <conio.h> 

//控制键 上、下、左、右 控制方向,'q' 退出 

#define KEY_UP 'w'  
#define KEY_LEFT 'a' 
#define KEY_RIGHT 'd' 
#define KEY_DOWN 's' 
#define KEY_QUIT 'q' 

//游戏环节 
bool quit = false; 
do {
	if(_kbhit()){ 
		//玩家按键 
		char ch = _getch(); 
		if (ch == KEY_UP){ 
			gameControl(UP); 
		}else if(ch == KEY_DOWN){ 
			gameControl(DOWN); 
		}else if(ch == KEY_LEFT){ 
			gameControl(LEFT); 
		}else if(ch == KEY_RIGHT){ 
			gameControl(RIGHT); 
		}else if(ch == KEY_QUIT){ 
			quit = true; 
		} 
	}
	
	Sleep(100); 
}while(quit==false); //!quit

3.3 推箱子控制

/********************************************** 
 *实现游戏四个方向(上、下、左、右)的控制 
 * 输入: 
 * direct - 人前进方向 
 * 输出: 无 
 **********************************************/ 
void gameControl(enum _DIRECTION direct) {
	struct _POS next_pos = man; 
	struct _POS next_next_pos = man; 
	
	switch (direct) { 
	case UP: 
		next_pos.x--; 
		next_next_pos.x -= 2; 
		break; 
	
	case DOWN: 
		next_pos.x++; 
		next_next_pos.x += 2; 
		break; 
	
	case LEFT: 
		next_pos.y--; 
		next_next_pos.y -= 2; 
		break; 
	
	case RIGHT: 
		next_pos.y++; 
		next_next_pos.y += 2; 
		break; 
	}
	
	//宏展开 next_pos.x>=0 && next_pos.x<LINE && next_pos.y>=0 && next_pos.y <COLUMN 
	if( isValid(next_pos) && map[next_pos.x][next_pos.y] == FLOOR ){// 人的前方是地板 
		changeMap(&next_pos, MAN); //小人前进一格 
		changeMap(&man, FLOOR); 
		man = next_pos; 
	}else if(isValid(next_next_pos) && map[next_pos.x][next_pos.y] == BOX){//人的前方是箱子 
		//两种情况,箱子前面是地板或者是箱子目的地
		if( map[next_next_pos.x][next_next_pos.y] == FLOOR){ 
			changeMap(&next_next_pos, BOX); 
			changeMap(&next_pos, MAN); //小人前进一格
			changeMap(&man, FLOOR); 
			man = next_pos; 
		}else if(map[next_next_pos.x][next_next_pos.y] == BOX_DES){ 
			changeMap(&next_next_pos, HIT); 
			changeMap(&next_pos, MAN); //小人前进一格 
			changeMap(&man, FLOOR); 
			man = next_pos; 
		} 
	} 
}

3.4 游戏结束

/********************************************** 
 *判断游戏是否结束,如果不存在任何一个箱子目的地,就代表游戏结束 
 *输入: 无 
 *返回值: 
 * true - 游戏结束 false - 游戏继续 
 **********************************************/ 

bool isGameOver() { 
	for (int i = 0; i< LINE; i++) { 
		for (int j = 0; j < COLUMN; j++) { 
			if (map[i][j] == BOX_DES) 
				return false; 
		} 
	}return true; 
}

/**********************************************
 *游戏结束场景,在玩家通关后显示 
 *输入: 
 * bg - 背景图片变量的指针 
 *返回值: 无 
 **********************************************/ 
void gameOverScene(IMAGE *bg) { 
	putimage(0, 0, bg); 
	settextcolor(WHITE); 
	RECT rec = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT }; 
	settextstyle(20, 0, _T("宋体")); 
	drawtext(_T("恭喜您~ \n 您终于成为了一个合格的搬箱子老司机!"), 
	&rec, DT_CENTER | DT_VCENTER | DT_SINGLELINE); }

//main 函数中 

if(isGameOver()){ 
	gameOverScene(&bg_img); 
	quit = true; 
}
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值