目录
一.游戏设计目的
二.学习内容
三.游戏的玩法
四.游戏的设计思路
五.游戏的界面图
编辑编辑
六.游戏代码
- 个人主页:北·海
- CSDN新晋作者
- 欢迎 点赞✍评论⭐收藏
- ✨收录专栏:C/C++
- 希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!
#include
#include
#include
#include
#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
#define KEY_UP 'w'
#define KEY_DOWN 's'
#define KEY_LEFT 'a'
#define KEY_RIGHT 'd'
#define KEY_QUIT 'q'
#define STEP_MAX 10
#define isVald(pos) pos.x >= 0 && pos.x < LINE && pos.y >= 0 && pos.y < COLUMN
using namespace std;
// 墙 : 0 地板 ; 1 箱子目的地 : 2 小人 : 3
//箱子 : 4 箱子命中目标 : 5
enum _PROPS{
WALL,
FLOOR,
BOX_DES,
MAN,
BOX,
HIT, //箱子命中目标
PER_BOX_DES,//人在目的地上
ALL //上面不设定值,这个刚好为道具的数量 为6
};
enum _DIRECTION {
UP,
DOWN,
LEFT,
RIGHT
};
struct _POS {
//人所在的位置
int x;
int y;
}man;
int step_count = 0;//统计走的步数
IMAGE images[ALL];
//地图
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 },
};
void gameOverSence(IMAGE* bg,char* text =nullptr) {
putimage(0, 0, bg);
settextcolor(WHITE);
RECT rec = { 0,0,SCREEN_WIDTH,SCREEN_HEIGHT };
settextstyle(20, 0, "宋体");
drawtext(text, &rec, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
//判断游戏是否正常结束
bool isGameover() {
//判断地图中是否还有2
for (int i = 0; i < LINE; i++) {
for (int j = 0; j < COLUMN; j++) {
if (map[i][j] == BOX) return false;
}
}
return true;
}
//判断游戏是否失败结束
bool isFail() {
//判断步数是否超过,超过则结束
if (step_count > STEP_MAX) {
return true;
}
return false;
}
void changeMap(struct _POS* pos,enum _PROPS prop) {
//prop - 道具的类型
map[pos->x][pos->y] = prop;
putimage(START_X + pos->y * RATIO, START_Y + pos->x * RATIO, &images[prop]);
}
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;
}
//人可以从箱子目的地上走过去
if (isVald(next_pos) && map[next_pos.x][next_pos.y] == FLOOR ) { //前面是空地
//优化为指针,可以节约内存
if (map[man.x][man.y] == PER_BOX_DES) {
changeMap(&next_pos, MAN);
changeMap(&man, BOX_DES);
man = next_pos;
}
else {
changeMap(&next_pos, MAN);//人的下一格
changeMap(&man, FLOOR);//人的位置设置为地板或者目的地
man = next_pos;
}
step_count++;
}
else if (isVald(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;
}
step_count++;
}
else if (isVald(next_pos) && map[next_pos.x][next_pos.y] == BOX_DES) {
//人的前面是目的地,将目的地改为人,将人的地方改为空地
changeMap(&next_pos, PER_BOX_DES);
changeMap(&man, FLOOR);
man = next_pos;
step_count++;
}
else if (isVald(next_pos) && map[next_pos.x][next_pos.y] == HIT) {
//前面是箱子在目的地上,目的地前面是箱子/空地
if (map[next_next_pos.x][next_next_pos.y] == FLOOR) {
//前面的前面是空地
changeMap(&next_next_pos, BOX);
changeMap(&next_pos, PER_BOX_DES);
changeMap(&man,FLOOR);
man = next_pos;
step_count++;
}
//非空地不做处理
}
//扩展项 :
//人的前面是目的地,将目的地改为人,将人的地方改为空地,
//人的当前位置是目的地,前面是空地时候,将人前面的位置改为人,将目的地位置改为目的地
//人可以将箱子从箱子目的地上推开
//统计人走的步数,可以指定步数,如果超过该步数,则显示失败,否则显示成功
}
int main() {
//搭建游戏台
IMAGE bg_img;
initgraph(SCREEN_WIDTH, SCREEN_HEIGHT,1);
loadimage(&bg_img, "blackground.bmp", SCREEN_WIDTH, SCREEN_HEIGHT,true);
putimage(0, 0, &bg_img);
//加载道具图标
loadimage(&images[WALL], "wall_right.bmp", RATIO, RATIO, true);
loadimage(&images[FLOOR], "floor.bmp", RATIO, RATIO, true);
loadimage(&images[BOX_DES], "des.bmp", RATIO, RATIO, true);
loadimage(&images[MAN], "man.bmp", RATIO, RATIO, true);
loadimage(&images[BOX], "box.bmp", RATIO, RATIO, true);
loadimage(&images[HIT], "box.bmp", RATIO, RATIO, true);
loadimage(&images[PER_BOX_DES], "man.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(START_X +j * RATIO, START_Y +i * RATIO, &images[map[i][j]]);
}
}
//热键控制
bool quit = false;
do {
//keyboardhit 如果有敲击键盘则返回true
if (_kbhit()) {
char ch;
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 (isFail()) {
//是否失败结束
gameOverSence(&bg_img, (char*)"很遗憾,没能通过此关卡");
quit = true;
}
if (isGameover()) {
//正常结束
gameOverSence(&bg_img, (char*)"恭喜你~,成为一名合格的搬箱子老司机");
quit = true;
}
Sleep(100);
}
} while (quit == false);
system("pause");
//游戏结束,释放资源
closegraph();
return 0;
}