卷二:C++图形编程第2篇 推箱子

本项目利用easyX图形库开发了一款推箱子游戏,通过控制键进行操作,包括上下左右移动及退出游戏等功能。游戏包含六个基本元素:墙、地板、人、箱子、目的地及箱子与目的地结合的状态。

描述:本项目采用easyX图形库开发,easyX非常适合初学者学习图形开发基础知识,大小才十几MB,调用函数接口一个介绍书全部搞定。

总结:采用面向流程的开发方法,学完C语言联系的不错项目;

解决问题的流程,先设计好哪些功能,每一个功能函数嵌套函数设计,遇到问题先设计函数再实现。

效果:

#include <graphics.h>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <conio.h>
//控制键 上、下、左、右 控制方向,'q' 退出
#define KEY_UP 'w' //char 'a'
#define KEY_LEFT 'a'
#define KEY_RIGHT 'd'
#define KEY_DOWN 's'
#define KEY_QUIT 'q'

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]; //一共六种像素图片组成:墙、人、地板、箱子、目的地、墙和箱子结合
/*游戏地图*/
/*
map[i][j]的每一个值填充6种像素图片就构成了整个地图
为0表示这是一块墙, 为1代表地板,为2代表人
为3代表箱子,为4代表目的地,为5代表箱子和目的地已经结合
//最好用枚举类型来表示最好,不让人可读性太差
*/
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 },
};

/**********************************************
*实现游戏四个方向(上、下、左、右)的控制
* 输入:
* 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;
	}
	}
}


/**********************************************
*判断游戏是否结束,如果不存在任何一个箱子目的地,就代表游戏结束
*输入: 无
*返回值:
* 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);
}




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]]); //这个像素位置图片显示较难理解
	}
	}

//	热键定义: 左 => a 下=> s 上=> w 右 => d 退出 => 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);
		if(isGameOver()){
			gameOverScene(&bg_img);
			quit = true;
		}
	}while(quit==false); //!quit
	system("pause");
		//main 函数中

	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值