C++ 推箱子小游戏

1、简介

利用esayx简易图形库实现一个推箱子游戏,源码可运行无问题,素材可加我qq要。

2、环境

vs2022,easyx官网,下载后直接应用到vs中。

3、源码
#include<graphics.h>
#include<iostream>
#include<string>
#include<stdlib.h>
#include<Windows.h>
#include<conio.h> // 获取热键头文件

// 模型图片大小
#define RATIO 61
// 屏幕大小
#define SCREEN_WIDTH 960
#define SCREEN_HEIGHT 768

// 定义键位
#define KEY_UP		'w'
#define KEY_LEFT	'a'
#define KEY_RIGHT	'd'
#define KEY_DOWN	's'
#define KEY_QUIT	'q'

using namespace std;

/*
* 墙 => 0 WALL,
* 地板 => 1 FLOOR,
* 箱子目的地 => 2 BOX_DES,
* 小人 => 3 MAN,
* 箱子 => 4 BOX,
* 箱子命中目标 => 5 HIT
*/

// 定义角色类型
enum _PROPS {
	WALL, //0
	FLOOR,//1
	BOX_DES,//2
	MAN,//3
	BOX,//4
	HIT, //5
	ALL
};

//游戏方向控制
enum _DIRECTION {
	UP,
	DOWN,
	LEFT,
	RIGHT
};

// 地图二维数组大小
const int LINE = 9;
const int COLUMN = 12;
// 地图初始坐标
const int init_xlabel = (SCREEN_WIDTH - COLUMN * RATIO) / 2;
const int init_ylabel = (SCREEN_HEIGHT - LINE * RATIO) / 2;

//小人位置
typedef struct _pos {
	int x;
	int y;
}_POS;

IMAGE images[ALL];
_POS man;
// 一共有多少个目标节点
const int num = 4;
_POS des_coordinate[num] = {
	{2, 5},
	{2, 8},
	{4, 3},
	{6, 2}
};
// 当前都多少个箱子在目的地上
int des_num = 0;

/* 游戏地图 */
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, 1, 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 },
};

/****************
* 功能:更改地图信息,并显示
* 输入:pos:要更新的地图位置地址
*	   pros:将该位置更新为的值
* 输出:无
****************/
void mapChange(_POS *pos, enum _PROPS pros) {
	map[pos->x][pos->y] = pros;
	putimage(init_xlabel + RATIO * pos->y, init_ylabel + RATIO * pos->x, &images[pros]);
}

/****************
* 功能:判断下标是否越界
* 输入:pos:要更新的地图位置地址
* 输出:ture没有越界,false越界
****************/
bool isVaild(_POS* pos) {
	if (pos->x >= 0 && pos->x < LINE && pos->y >= 0 && pos->y < COLUMN)
		return true;
	return false;
}
/****************
* 功能:判断某坐标是否为目标值
* 输入:pos:要判断的位置
* 输出:ture为目标值,false不为目标值
****************/
bool isDes(_POS* pos) {
	for (int i = 0; i < num; ++i) {
		if ((des_coordinate[i].x == pos->x) && (des_coordinate[i].y == pos->y))
			return true;
	}
	return false;
}
/****************
* 功能:指定人物朝着某方向前进
* 输入:前进方向
* 输出:无
****************/
bool gameContrl(enum _DIRECTION dir) {

	// 人物前进的位置
	_POS next_pos = man;
	// 人物前进的位置的前一个
	_POS next_next_pos = man;
	switch (dir)
	{
	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;
	default:
		break;
	}

	if (isVaild(&next_pos) && map[next_pos.x][next_pos.y] == FLOOR) { // 后面为地板
		mapChange(&next_pos, MAN);
		if (isDes(&man)) {
			mapChange(&man, BOX_DES);
		}
		else {
			mapChange(&man, FLOOR);
		}
		man = next_pos;
	}

	if (isVaild(&next_pos) && map[next_pos.x][next_pos.y] == BOX_DES) { // 后面为目的地
		mapChange(&next_pos, MAN);
		if (isDes(&man)) {
			mapChange(&man, BOX_DES);
		}
		else {
			mapChange(&man, FLOOR);
		}
		man = next_pos;
	}

	if (isVaild(&next_pos) && map[next_pos.x][next_pos.y] == BOX) { // 后面为箱子
		if (isVaild(&next_pos) && map[next_next_pos.x][next_next_pos.y] == FLOOR) { //箱子后为地板,可走
			mapChange(&next_next_pos, BOX);
			mapChange(&next_pos, MAN);
			if(isDes(&man)){
				mapChange(&man, BOX_DES);
			}else{
				mapChange(&man, FLOOR);
			}
			man = next_pos;
			if (isDes(&next_pos)) {
				des_num--;
			}
		} else if (isVaild(&next_pos) && map[next_next_pos.x][next_next_pos.y] == BOX_DES) { //箱子后为目的地,可走
			mapChange(&next_next_pos, BOX);
			mapChange(&next_pos, MAN);
			if (isDes(&man)) {
				mapChange(&man, BOX_DES);
			}
			else {
				mapChange(&man, FLOOR);
			}
			man = next_pos;
			if (isDes(&next_next_pos)) {
				des_num++;
				if (des_num == 4) {
					return true;
				}
			}
		}
	}

	return false;
}

int main() {
	// 初始化界面 => (960, 768)
	initgraph(960, 768);

	// 加载背景
	IMAGE img_bg;
	loadimage(&img_bg, _T("blackground.bmp"), SCREEN_WIDTH, SCREEN_HEIGHT, true);
	putimage(0, 0, &img_bg);

	/*
	* 墙 => 0 WALL,
	* 地板 => 1 FLOOR,
	* 箱子目的地 => 2 BOX_DES,
	* 小人 => 3 MAN,
	* 箱子 => 4 BOX,
	* 箱子命中目标 => 5 HIT
	*/
	
	loadimage(&images[WALL], _T("wall_right.bmp"), RATIO, RATIO, true);
	loadimage(&images[FLOOR], _T("floor.bmp"), RATIO, RATIO, true);
	loadimage(&images[BOX_DES], _T("des.bmp"), RATIO, RATIO, true);
	loadimage(&images[MAN], _T("man.bmp"), RATIO, RATIO, true);
	loadimage(&images[BOX], _T("box.bmp"), RATIO, RATIO, true);

	/* 初始化地图元素 */
	for (int i = 0; i < LINE; ++i) {
		for (int j = 0; j < COLUMN; ++j) {
			if (map[i][j] == MAN) {
				man.x = i;
				man.y = j;
			}
			putimage(init_xlabel + RATIO * j, init_ylabel + RATIO * i, &images[map[i][j]]);
		}
	}

	bool quit = false;
	do {
		if (_kbhit()) { // 有键盘事件,该函数返回true
			// 拿到按下的键位
			char ch = _getch();
			if(ch == KEY_UP){
				if (gameContrl(UP)) {
					quit = true;
				}
			}else if(ch == KEY_DOWN){
				if (gameContrl(DOWN)) {
					quit = true;
				}
			}else if(ch == KEY_LEFT){
				if (gameContrl(LEFT)) {
					quit = true;
				}
			}else if(ch == KEY_RIGHT){
				if (gameContrl(RIGHT)) {
					quit = true;
				}
			}else if(ch == KEY_QUIT){
				quit = true;
			}
		}

	} while (quit == false);
	
	// 设置字体颜色
	settextcolor(YELLOW);
	//设置字体格式
	settextstyle(30, 0, _T("微软雅黑"));

	outtextxy(SCREEN_WIDTH / 2 - 75, SCREEN_HEIGHT / 2 - 15, _T("YOU ARE WIN!!!"));

	system("pause");

	closegraph();

	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值