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