C语言实现简单的推箱子游戏

本文实例为大家分享了C语言实现简单的推箱子游戏的具体代码,供大家参考,具体内容如下

项目实现的具体方案:

先安装VS2019,后安装画图工具Easyx,安装以后就可以将推箱子中的(人物,墙壁,箱子目的地,箱子)的图片加载到程序中显示出来。游戏的实现是通过程序读取键盘中输入的字母,后控制加载到程序中的人物图片的移动实现小人的移动,通过人物图片和地板图片交换位置实现人物的行走,如果人物前面是箱子图片,箱子图片前面是地板图片,则人物图片和箱子图片一起移动,直到箱子图片前面是箱子目的地图片则箱子图片将箱子目的地替换,从而实现将箱子推到箱子目的地上。这就是实现游戏的思路,程序中还有各种细节在下面进行讲解。在开始编写程序时先创建一个c++空项目,把cpp文件和地图中相对应的元素图片(人物,墙壁,箱子目的地,箱子)放在同一个目录下面。

1、开始先进行地图大小的实现

(1)我们先初始化图形界面的大小

#define SCREEN_WIDTH 976
#define SCREEN_HEIGHT 549    
 
//窗口初始化
    initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);//括号中的是窗口的长和宽为了以后可以方便改变大小所以进行了宏定义

(2)窗口大小初始化完以后进行开始游戏界面的实现

IMAGE bg_img2; //申请一个句柄用来存放图片
    
//游戏开始背景背景图
    loadimage(&bg_img2,_T("blachground.jpg"),732,549,true); //将图片blachground.jpg加载到&bg_img2
    GameStarSCREEN(&bg_img2);
 
    Sleep(1000); //休眠1000毫秒
 
//函数GameStarSCREEN的实现
//游戏开始界面
void GameStarSCREEN(IMAGE *bg){
    putimage(0,0,bg); //把图片播放在(0,0)坐标
 
    //设置窗口标题
    HWND window = GetHWnd();//获取窗口
    SetWindowText(window,_T("推箱子 ***"));//设置窗口标题
 
    //设置文本样式及颜色
    settextcolor(WHITE);
    settextstyle(20,0,_T("宋体"));
    outtextxy(LINE1,COW1,_T("欢迎进入本人设置的游戏"));
}

游戏开始界面效果

C语言实现简单的推箱子游戏_第1张图片

(3)游戏开始界面设置完以后进行游戏操作指南和游戏规则的界面设置

//游戏正在进行界面
void BeingGameSCREEN(){
    //清除界面
    cleardevice();
    //画一个矩形
    rectangle(762,30,952,244);
    settextcolor(WHITE);  //设置字体颜色
    settextstyle(15,0,_T("宋体")); //设置字体的宽度和高度以及字体的类型
    outtextxy(772,40,_T("游戏操作指南:")); //在对应的坐标位置输出引号内的字符串
    outtextxy(772,60,_T("按 W 向上移动"));
    outtextxy(772,75,_T("按 S 向下移动"));
    outtextxy(772,90,_T("按 A 向左移动"));
    outtextxy(772,105,_T("按 D 向右移动"));
    
    outtextxy(772,130,_T("温馨提示:"));
    outtextxy(772,170,_T("请在 58 步以内完成任务"));
    outtextxy(772,200,_T("退出请按 Q"));
 
    rectangle(922,450,762,264);
    outtextxy(772,284,_T("您以走的步数为:"));
}

游戏操作指南效果图

C语言实现简单的推箱子游戏_第2张图片

 (4)进行游戏地图的实现

先定义一个全局的二维数组用来保存地图中的(人物,墙壁,箱子目的地,箱子)元素

int map[COW][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},
};

定义一个枚举类型用来设置地图中的(人物,墙壁,箱子目的地,箱子)元素

enum _PROPS{
    WALL_RIGHT, //墙壁为数字0
    FLOOR,    //地板为数字1
    DES,    //箱子目的地为数字2
    MAN,    //人物为数字3
    BOX,    //箱子为数字4
    BOX_HIT,    //把箱子推到箱子目的地为数字5
    MAN_DES, //人站在目的地上为数字6
    ALL //全部道具的数量为数字7
}poc;

地图定义完以后将地图元素加在到二维数组中

#define RATIO 61 //地图元素大小
 
//申请一个全局的一维的数组句柄
IMAGE images[ALL];    
 
    //加载地图元素
    loadimage(&images[WALL_RIGHT],_T("wall_right.bmp"),RATIO,RATIO,true); 
    loadimage(&images[FLOOR],_T("floor.bmp"),RATIO,RATIO,true);
    loadimage(&images[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[BOX_HIT],_T("box.bmp"),RATIO,RATIO,true);
    loadimage(&images[MAN_DES],_T("man.bmp"),RATIO,RATIO,true);
 
//用for循环遍历二维数组,二维数组中相应坐标对应的数字与后来设置的以为数组中对应的枚举值相对应这样方可进行地图的实现
    for(int i=0;i 
 

地图实现的效果图

C语言实现简单的推箱子游戏_第3张图片

 2、进行游戏控制环节的实现,游戏的控制是通过控制小人的移动实现

所以我们先定义一个全局的结构体来表示小人在地图中的位置

struct _pos{
  int x; //小人的横坐标
  int y; //小人的纵坐标
};
 
struct _pos man;

小人坐标定义好以后我们要获取小人在地图中的坐标才能对小人进行移动,小人的坐标随我们不断移动而改变所以饿哦们要不断获取小人的坐标

for(int i=0;i 
 

(1)定义一个枚举类型用来表示移动的方向

//枚举控制地图中小人的运动方向
enum DURATION{
    UP,
    DOWN,
    LEFT,
    RIGHT
};
 
enum DURATION direct;

(2)获取小人位置后对小人进行移动

bool quit=false; //定义一个布尔类型
 
    do{
        if(_kbhit()){ //识别从键盘输入的字母
            char ch=_getch(); //从键盘输入字母
            cnt++;
            Record_Steps(); //记录走过的步数,每次进入识别键盘输入说明移动了一次从而进行步数加一
            if(ch==KEY_UP){
                gameControal(UP);
            }else if(ch==KEY_DOWN){
                gameControal(DOWN);
            }else if(ch==KEY_LEFT){
                gameControal(LEFT);
            }else if(ch==KEY_RIGHT){
                gameControal(RIGHT);
            }else if(ch==KEY_QUIT){
                quit=true;
                GameOverSCREEN(&bg_img);
            }if(isGameOver()){
                quit=true;
                GameOverSCREEN(&bg_img);
            }if(cnt>LEN){
                quit=true;
                FalseGameOverSCREEN(&bg_img1);
            }
        }
        Sleep(100);
    }while(quit==false);

(3)用宏定义表示从键盘输入的字母

#define KEY_UP 'W'
#define KEY_DOWN 'S'
#define KEY_LEFT 'A'
#define KEY_RIGHT 'D'
#define KEY_QUIT 'Q'

(4)接下来进行人物的移动方向的判断

//控制程序运行小人移动和方块移动
void gameControal(enum DURATION direct){
    int x=man.x;
    int y=man.y;
//对向上移动的控制
    if(direct==UP){
        if((x-1)>=STAR&&map[x-1][y]==DES){
            mapChange(x-1,y,MAN_DES);
            mapChange(x,y,FLOOR);
            man.x=x-1;
        }else if(map[x][y]==MAN_DES&&map[x-1][y]==FLOOR){
            mapChange(x,y,DES);
            mapChange(x-1,y,MAN);
            man.x=x-1;
        }else if((x-1)>=STAR&&map[x-1][y]==FLOOR){
            mapChange(x-1,y,MAN);
            mapChange(x,y,FLOOR);
            man.x=x-1;
        }else if(map[x-1][y]==BOX_HIT&&map[x-2][y]==FLOOR){
                mapChange(x-2,y,BOX);
                mapChange(x-1,y,MAN_DES);
                mapChange(x,y,FLOOR);
                man.x=x-1;
        }else if(map[x][y]==MAN_DES&&map[x-1][y]==BOX&&map[x-2][y]==FLOOR){
                mapChange(x-2,y,BOX);
                mapChange(x-1,y,MAN);
                mapChange(x,y,DES);
                man.x=x-1;
        }else if((x-1)>=STAR&&map[x-1][y]==BOX){
            if(map[x-2][y]==FLOOR){
            mapChange(x-1,y,MAN);
            mapChange(x,y,FLOOR);
            mapChange(x-2,y,BOX);
            man.x=x-1;
                }else if(map[x-2][y]==DES){
                mapChange(x-1,y,MAN);
                mapChange(x,y,FLOOR);
                mapChange(x-2,y,BOX_HIT);
                man.x=x-1;
            }
        }
//对向下移动的控制
    }else if(direct==DOWN){
        if((x+1)>=STAR&&map[x+1][y]==DES){
            mapChange(x+1,y,MAN_DES);
            mapChange(x,y,FLOOR);
            man.x=x+1;
        }else if(map[x][y]==MAN_DES&&map[x+1][y]==FLOOR){
            mapChange(x,y,DES);
            mapChange(x+1,y,MAN);
            man.x=x+1;
        }else if((x+1)=STAR&&map[x][y+1]==DES){
            mapChange(x,y+1,MAN_DES);
            mapChange(x,y,FLOOR);
            man.y=y+1;
        }else if(map[x][y]==MAN_DES&&map[x][y+1]==FLOOR){
            mapChange(x,y,DES);
            mapChange(x,y+1,MAN);
            man.y=y+1;
        }else if((y+1)=STAR&&map[x][y-1]==DES){
            mapChange(x,y-1,MAN_DES);
            mapChange(x,y,FLOOR);
            man.y=y-1;
        }else if(map[x][y]==MAN_DES&&map[x][y-1]==FLOOR){
            mapChange(x,y,DES);
            mapChange(x,y-1,MAN);
            man.y=y-1;
        }else if((y-1)>=0&&map[x][y-1]==FLOOR){
            mapChange(x,y-1,MAN);
            mapChange(x,y,FLOOR);
            man.y=y-1;
        }else if(map[x][y-1]==BOX_HIT&&map[x][y-2]==FLOOR){
                mapChange(x,y-2,BOX);
                mapChange(x,y-1,MAN_DES);
                mapChange(x,y,FLOOR);
                man.y=y-1;
        }else if(map[x][y]==MAN_DES&&map[x][y-1]==BOX&&map[x][y-2]==FLOOR){
                mapChange(x,y-2,BOX);
                mapChange(x,y-1,MAN);
                mapChange(x,y,DES);
                man.y=y-1;
        }else if((y-1)>=0&&map[x][y-1]==BOX){
            if(map[x][y-2]==FLOOR){
            mapChange(x,y-1,MAN);
            mapChange(x,y,FLOOR);
            mapChange(x,y-2,BOX);
            man.y=y-1;
            }else if(map[x][y-2]==DES){
                mapChange(x,y-1,MAN);
                mapChange(x,y,FLOOR);
                mapChange(x,y-2,BOX_HIT);
                man.y=y-1;
            }
        }
    }
}

(5)对人物移动方向判断后进行地图中元素位置进行改变才能真正实现人物的移动

//改变地图元素
void mapChange(int line,int colum,enum _PROPS poc){
    map[line][colum]=poc;
    putimage(colum*RATIO,line*RATIO,&images[poc]);
}

3、人物控制结束以后进行游戏结束界面的设计

(1)在规定步数内完成游戏的背景

//游戏结束背景
void GameOverSCREEN(IMAGE *bg){
    cleardevice();
    putimage(0,0,bg);
    settextcolor(WHITE);
    RECT rec={0,0,SCREEN_WIDTH,SCREEN_HEIGHT};
    settextstyle(20,0,_T("宋体"));
    outtextxy(LINE1,COW1,_T("恭喜完成了本游戏你真棒"));
    outtextxy(LINE2,COW2,_T("请按Q退出游戏"));
}

效果图

C语言实现简单的推箱子游戏_第4张图片

(1)不在规定步数内完成游戏背景

//游戏非正常结束背景
void FalseGameOverSCREEN(IMAGE *bg){
    cleardevice();
    putimage(0,0,bg);
    settextcolor(WHITE);
    settextstyle(20,0,_T("宋体"));
    outtextxy(LINE1,COW1,_T("小菜鸡这都完成不了真蠢"));
    outtextxy(LINE2,COW2,_T("请按Q退出游戏"));
}

效果图

C语言实现简单的推箱子游戏_第5张图片

4、具体代码实现

(1)头文件编写

#define LINE1 366 
#define COW1 183
#define LINE2 427
#define COW2 244
 
#define RATIO 61
#define LEN 100
#define STAR 0
 
#define SCREEN_WIDTH 976
#define SCREEN_HEIGHT 549
 
#define COW 9
#define COLUMN 12
 
#define KEY_UP 'W'
#define KEY_DOWN 'S'
#define KEY_LEFT 'A'
#define KEY_RIGHT 'D'
#define KEY_QUIT 'Q'
 
int cnt=STAR;
 
//枚举优化代码表示道具
enum _PROPS{
    WALL_RIGHT,
    FLOOR,
    DES,
    MAN,
    BOX,
    BOX_HIT,
    MAN_DES,
    ALL
}poc;
 
//enum _PROPS poc;
 
//小人在二维数组中的位置
struct _pos{
  int x;
  int y;
};
 
struct _pos man;
 
//窗口初始化
IMAGE images[ALL];
 
//地图的实现
int map[COW][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},
};
 
//判断游戏是否结束
//return->false 游戏未结束 return->true 游戏结束
int isGameOver(){
    for(int i=0;i=STAR&&map[x-1][y]==DES){
            mapChange(x-1,y,MAN_DES);
            mapChange(x,y,FLOOR);
            man.x=x-1;
        }else if(map[x][y]==MAN_DES&&map[x-1][y]==FLOOR){
            mapChange(x,y,DES);
            mapChange(x-1,y,MAN);
            man.x=x-1;
        }else if((x-1)>=STAR&&map[x-1][y]==FLOOR){
            mapChange(x-1,y,MAN);
            mapChange(x,y,FLOOR);
            man.x=x-1;
        }else if(map[x-1][y]==BOX_HIT&&map[x-2][y]==FLOOR){
                mapChange(x-2,y,BOX);
                mapChange(x-1,y,MAN_DES);
                mapChange(x,y,FLOOR);
                man.x=x-1;
        }else if(map[x][y]==MAN_DES&&map[x-1][y]==BOX&&map[x-2][y]==FLOOR){
                mapChange(x-2,y,BOX);
                mapChange(x-1,y,MAN);
                mapChange(x,y,DES);
                man.x=x-1;
        }else if((x-1)>=STAR&&map[x-1][y]==BOX){
            if(map[x-2][y]==FLOOR){
            mapChange(x-1,y,MAN);
            mapChange(x,y,FLOOR);
            mapChange(x-2,y,BOX);
            man.x=x-1;
                }else if(map[x-2][y]==DES){
                mapChange(x-1,y,MAN);
                mapChange(x,y,FLOOR);
                mapChange(x-2,y,BOX_HIT);
                man.x=x-1;
            }
        }
    }else if(direct==DOWN){
        if((x+1)>=STAR&&map[x+1][y]==DES){
            mapChange(x+1,y,MAN_DES);
            mapChange(x,y,FLOOR);
            man.x=x+1;
        }else if(map[x][y]==MAN_DES&&map[x+1][y]==FLOOR){
            mapChange(x,y,DES);
            mapChange(x+1,y,MAN);
            man.x=x+1;
        }else if((x+1)=STAR&&map[x][y+1]==DES){
            mapChange(x,y+1,MAN_DES);
            mapChange(x,y,FLOOR);
            man.y=y+1;
        }else if(map[x][y]==MAN_DES&&map[x][y+1]==FLOOR){
            mapChange(x,y,DES);
            mapChange(x,y+1,MAN);
            man.y=y+1;
        }else if((y+1)=STAR&&map[x][y-1]==DES){
            mapChange(x,y-1,MAN_DES);
            mapChange(x,y,FLOOR);
            man.y=y-1;
        }else if(map[x][y]==MAN_DES&&map[x][y-1]==FLOOR){
            mapChange(x,y,DES);
            mapChange(x,y-1,MAN);
            man.y=y-1;
        }else if((y-1)>=0&&map[x][y-1]==FLOOR){
            mapChange(x,y-1,MAN);
            mapChange(x,y,FLOOR);
            man.y=y-1;
        }else if(map[x][y-1]==BOX_HIT&&map[x][y-2]==FLOOR){
                mapChange(x,y-2,BOX);
                mapChange(x,y-1,MAN_DES);
                mapChange(x,y,FLOOR);
                man.y=y-1;
        }else if(map[x][y]==MAN_DES&&map[x][y-1]==BOX&&map[x][y-2]==FLOOR){
                mapChange(x,y-2,BOX);
                mapChange(x,y-1,MAN);
                mapChange(x,y,DES);
                man.y=y-1;
        }else if((y-1)>=0&&map[x][y-1]==BOX){
            if(map[x][y-2]==FLOOR){
            mapChange(x,y-1,MAN);
            mapChange(x,y,FLOOR);
            mapChange(x,y-2,BOX);
            man.y=y-1;
            }else if(map[x][y-2]==DES){
                mapChange(x,y-1,MAN);
                mapChange(x,y,FLOOR);
                mapChange(x,y-2,BOX_HIT);
                man.y=y-1;
            }
        }
    }
}

(2)main文件的实现

#include
#include
#include
#include
#include
#include
#pragma comment(lib,"winmm.lib")
 
#include "box.h"
 
using namespace std;
 
int main(void){
 
    //申请一个句柄
    IMAGE bg_img;
    IMAGE bg_img1;
    IMAGE bg_img2;
 
    //窗口初始化
    initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
 
    //游戏开始背景背景图
    loadimage(&bg_img2,_T("blachground.jpg"),732,549,true);
    GameStarSCREEN(&bg_img2);
 
    Sleep(1000);
 
    //游戏正在进行界面
    BeingGameSCREEN();
 
    //加载游戏未在规定规则内完成的背景
    loadimage(&bg_img1,_T("blackground.jpg"),732,549,true);
 
    //加载游戏在规定规则内完成的背景图
    loadimage(&bg_img,_T("blackground.jpg"),732,549,true);
 
    //加载背景音乐
    mciSendString(_T("play 南方.mp3 repeat"), 0, 0, 0);
 
    //加载地图元素
    loadimage(&images[WALL_RIGHT],_T("wall_right.bmp"),RATIO,RATIO,true);
    loadimage(&images[FLOOR],_T("floor.bmp"),RATIO,RATIO,true);
    loadimage(&images[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[BOX_HIT],_T("box.bmp"),RATIO,RATIO,true);
    loadimage(&images[MAN_DES],_T("man.bmp"),RATIO,RATIO,true);
 
    for(int i=0;iLEN){
                quit=true;
                FalseGameOverSCREEN(&bg_img1);
            }
        }
        Sleep(100);
    }while(quit==false);
 
    system("pause");
 
    //游戏结束释放资源
    closegraph();
 
    return 0;
}

5、这是本人对推箱子游戏的见解如果有什么错误请指正

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

你可能感兴趣的:(C语言实现简单的推箱子游戏)