推箱子项目

#include<stdio.h>
#include<graphics.h>  //图形
#include<iostream>
#include<string>
#include<conio.h>  //热键

using namespace std;

//图像大小
#define RATIO 61

//初始化的地图大小
#define SCREEN_WIDTH 960
#define SCREEN_HEIGHT 768

//地图的二维数组
#define LINE 9
#define COLUMN 12

//控制键: 上,下,左,右 (控制方向)   'q'退出
#define KEY_UP       'w'       //char 'a'
#define KEY_DOWN     's'
#define KEY_LEFT     'a'
#define KEY_RIGHT   'd'
#define KEY_QUIT     'q'

//地图界面离(0,0)点的距离 (偏移量)
#define START_X 100
#define START_Y 100

//判断是否越界
#define isValid(pos) pos.x>=0 && pos.x<LINE &&pos.y>=0 && pos.y<COLUMN 

typedef enum _PROPS        PROPS;
typedef enum _DIRECTION    DIRECTION;
typedef struct _POS        POS;
//枚举 游戏道具
enum _PROPS{
	WALL,   //墙
	FLOOR,  //地板
	BOX_DES, //箱子目的地
	GIRL,  //主角
	BOX,   //箱子
	HIT,   //箱子命中目标
	ALL   //道具的数量

};

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

//结构体
struct _POS{
	int x;   //小人所在二维数组的行
	int y;   //小人所在二维数组的列

};

IMAGE images[ALL];

struct _POS girl; //结构体定义 (小人在二维数组的位置)

bool isDes = false;  //被覆盖的开关 

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


/********************************************** 
*判断游戏是否结束,如果不存在任何一个箱子目的地,就代表游戏结束 
*输入: 无 
*返回值: 
*	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("恭喜你!终于成为一名推箱子的老司机了"), &rec, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}


/************************
*改变游戏地图视图中的一格对应道具并重新显示
*输入:
*		line - 道具在地图数组的行标
*		column - 道具在地图数组的列下标
*		prop - 道具的类型
*返回值: 无
************************/
void changeMap(POS *pos, PROPS  prop){
	map[pos->x][pos->y] = prop;
	putimage(pos->y * RATIO+START_X, pos->x * RATIO+START_Y, &images[prop]);
};



/************************
*实现游戏四个方向(上 下 左 右)的控制'
*输入:
*direct - 人前进的方向
*输出: 无
************************/
void gameControl(DIRECTION direct){

	POS next_pos = girl;
	POS next_next_pos = girl;
	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;
	}

	//宏展开 #define isValid(pos) pos.x>=0 && pos.x<LINE &&pos.y>=0 && pos.y<COLUMN 
	if(isValid(next_pos) && map[next_pos.x][next_pos.y] == FLOOR){//人的前方是地板
		changeMap(&next_pos, GIRL); 

		if (isDes)
		{
			changeMap(&girl, BOX_DES);
			isDes = false;
		}
		else
		{
			changeMap(&girl, FLOOR);
		}
		
		girl = next_pos;
	}
	else if(isValid(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, GIRL);
			//changeMap(&girl, FLOOR);
					if (isDes)  
			{
				changeMap(&girl, BOX_DES);
				isDes = false;
			}
			else
			{
				changeMap(&girl, FLOOR);
			}
		
			girl = next_pos;
		}else if(map[next_next_pos.x][next_next_pos.y] == BOX_DES){  //下下一步是箱子目的地的话就说明,箱子的下一步是目的地(命中目标),女孩的下一步是箱子,所以女孩的位置改变为地板,所以不需要进行开关判断(因为女孩的位置没有到达目的地,所以不需要进行判断)
			changeMap(&next_next_pos, HIT);
			changeMap(&next_pos, GIRL);
			changeMap(&girl, FLOOR);
			girl = next_pos;
		}
	}
	else if(isValid(next_pos) && map[next_pos.x][next_pos.y] == BOX_DES){ //下一步是目的地的话就开启开关
		isDes = true;
		changeMap(&next_pos, GIRL);
		changeMap(&girl, FLOOR);
		girl = next_pos;
	}
	else if (isValid(next_pos) && map[next_pos.x][next_pos.y] == HIT && map[next_next_pos.x][next_next_pos.y] != WALL) {//女孩的下一步是命中目标的话,那就开启开关进行判断
		isDes = true;
		changeMap(&next_next_pos, BOX);
		changeMap(&next_pos, GIRL);   
		changeMap(&girl, FLOOR);
		girl = next_pos;
	}
}


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);

	//加载道具图形并存放进images数组里面
	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[GIRL], _T("girl.bmp"), RATIO, RATIO, true);
	loadimage(&images[BOX], _T("box.bmp"), RATIO, RATIO, true);
	loadimage(&images[HIT], _T("box.bmp"), RATIO, RATIO, true);

	//放置图形
	for(int i=0;i<9;i++){
		for(int j=0;j<12;j++){
			if(map[i][j] == GIRL){
				girl.x = i;  //结构体赋值
				girl.y = j;  //结构体赋值
			}
			putimage(j*RATIO+START_X, i*RATIO+START_Y, &images[map[i][j]]);
		}
	}

	//游戏环节
	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;
			}
			if(isGameOver()){
				gameOverScene(&bg_img); 
				quit = true;
			}

		}
		Sleep(100);
	}while(quit == false);


	system("pause");

	//游戏结束,释放资源
	closegraph();
	return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪人很热

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值