头文件:boxman.h
#define KEY_UP 'w'
#define KEY_DOWN 's'
#define KEY_LEFT 'a'
#define KEY_RIGHT 'd'
#define KEY_QUITE 'q'
#define MAP_X 9
#define MAP_Y 12
#define RATIO 61 //像素点
#define SCREEN_WIDTH 960
#define SCREEN_HEIGHT 768
#define isValid(pos) pos.x>=0 && pos.x<MAP_X&&pos.y>=0 &&pos.y<MAP_Y
typedef enum _PROPS PROPS;
typedef enum _DIRECTION DIRECTION;
typedef struct _POS POS;
struct _POS{
int x; //小人所在二维数组的行
int y; //小人所在二维数组的列
};
enum _PROPS{
WALL, //墙
FLOOR, //地板
BOX_DES,//箱子的目的地
MAN, //主角
BOX, //箱子
HIT, //箱子已经退到目的地
ALL //道具的个数
};
enum _DIRECTION{
UP,
DOWN,
LEFT,
RIGHT
};
.源文件 :boxman.cpp
#include<graphics.h>
#include<Windows.h>
#include<stdlib.h>
#include<string>
#include<conio.h>
#include"boxman.h"
using namespace std;
int hold=0; //用来标记是否小人踩在目的地上
struct _POS man; //小人在二维数组中的位置
IMAGE images[ALL]; //加载图片的数组
int map[MAP_X][MAP_Y]={
{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 changeMap(POS *pos,PROPS prop);
void gameControl(DIRECTION direction);
bool isGameover();
void Gameover(IMAGE *bg);
void Gamefalse(IMAGE *bg);
IMAGE bg_img; //用来承接图片
initgraph(960,768); //搭建戏台
loadimage(&bg_img,_T("blackground.bmp"), 960, 768,true);//加载图片
putimage(0,0,&bg_img); //显示图片
loadimage(&images[WALL],_T("wall.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);
loadimage(&images[HIT],_T("box.bmp"),RATIO,RATIO,true);
for(int i=0;i<MAP_X;i++){
for(int j=0;j<MAP_Y;j++){
if(map[i][j] == MAN){ //找到小人的位置
man.x = i;
man.y = j;
}
putimage(100+j*61, 150+i*61 ,&images[map[i][j]]);//对图片进行显示
}
}
bool quite = 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_QUITE){
quite = true;
}
if(isGameover()){
Gameover(&bg_img);
quite = true;
}
Sleep(100);
}
}while(!quite);
system("pause");
closegraph();
return 0;
}
/************
* 作用:显示道具
* line:道具在数组的列坐标
* cloumn:道具在数组的行坐标
* prop:道具的类型
*
**************/
void changeMap(POS *pos,PROPS prop){
map[pos->x][pos->y] = prop;
putimage(100+pos->y * RATIO, 150+pos->x * RATIO ,&images[prop]);
}
void gameControl(DIRECTION direction){
POS next_pos=man;
POS next_next_pos=man;
switch(direction){
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;
}
//isValid()为宏展开
if( isValid(next_pos)&& map[next_pos.x][next_pos.y]== FLOOR){ //判断是否为地板
if(hold==0){ //是否小人下面踩得的是目的地
changeMap(&next_pos,MAN);
changeMap(&man,FLOOR);
man = next_pos;
}else {
changeMap(&next_pos,MAN);
changeMap(&man,BOX_DES);
man = next_pos;
hold = 0;
}
}else if(isValid(next_pos)&& map[next_pos.x][next_pos.y]== BOX_DES){//小人前方是否为目的地
changeMap(&next_pos,MAN);
changeMap(&man,FLOOR);
man = next_pos;
hold =1;
}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){ //判断箱子前面是都为地板
if(hold == 0){
changeMap(&next_pos,MAN);
changeMap(&man,FLOOR);
man = next_pos;
changeMap(&next_next_pos,BOX);
}else{
changeMap(&next_pos,MAN);
changeMap(&man,BOX_DES);
man = next_pos;
changeMap(&next_next_pos,BOX);
}
}else if(map[next_next_pos.x][next_next_pos.y] == BOX_DES){ //判断箱子前方是否为目的地
changeMap(&next_pos,MAN);
changeMap(&man,FLOOR);
man = next_pos;
changeMap(&next_next_pos,HIT);
}
}else if(isValid(next_next_pos)&& map[next_pos.x][next_pos.y]== HIT){ //判断小人前方是否箱子目的地重合的地方
changeMap(&next_pos,MAN);
changeMap(&man,FLOOR);
man = next_pos;
changeMap(&next_next_pos,BOX);
hold =1;
}
}
/************
*判断游戏是否结束
*如果数组中不存在任何一个箱子目的地,就代表游戏结束
*
*
**************/
bool isGameover(){
int i,j;
for(i=0;i<MAP_X;i++){
for(j=0;j<MAP_Y;j++){
if(map[i][j] ==BOX_DES ){
return false;
}
}
}
return true;
}
/*
显示游戏结束画面
*/
void Gameover(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);
}