您的位置:首页 > 编程语言 > C语言/C++

C语言简单游戏编程学习入门之推箱子

2020-01-14 10:53 239 查看

运行结果预览图

源代码

#include<stdio.h>
#include<conio.h>
#include<windows.h>

//定义地图信息
#define row 8
#define col 8
int map[row][col]={
{0,0,1,1,1,0,0,0},
{0,0,1,4,1,0,0,0},
{0,0,1,0,1,1,1,1},
{1,1,1,2,0,2,4,1},
{1,4,0,2,5,1,1,1},
{1,1,1,1,2,1,0,0},
{0,0,0,1,4,1,0,0},
{0,0,0,1,1,1,0,0}
};

//人物位置
int person_x=4;
int person_y=4;

//定义代号
#define PERSON 5		//注意 人进了空地也显示人,所以9也是人的代号
#define PERSON_DESTINATION 9
#define person "人"
#define FLOOR 0			//空地
#define floor "  "
#define WALL 1			//墙壁
#define wall "■"
#define BOX 2 			//箱子
#define box "●"
#define DESTINATION 4 	//目的地
#define destination "☆"
#define PERFECT 6 		//箱子进了目的地
#define perfect "★"

//打印地图
void PrintMap();
//判断是否已经完成了游戏
int IsWin();
//gotoxy函数的实现,把光标移到到指定位置
void gotoxy(int x,int y);
//人物移动
void turn();

int main()
{
while(1)
{
PrintMap();
if(IsWin())
{
break;
}
turn();
}
printf("恭喜啦!\n");
return 0;
}

//打印地图
void PrintMap()
{
int i,j;
gotoxy(0,0);
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
switch(map[i][j])
{
case PERSON:
case PERSON_DESTINATION:
printf("%s",person);break;
case FLOOR:
printf("%s",floor);break;
case WALL:
printf("%s",wall);break;
case BOX:
printf("%s",box);break;
case DESTINATION:
printf("%s",destination);break;
case PERFECT:
printf("%s",perfect);break;
default:
printf("error!");
}
}
printf("\n");
}
printf("\n");
}

//判断是否已经完成了游戏(当没有箱子时,游戏成功)
int IsWin()
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
if(map[i][j]==BOX)
{
return 0;
}
}
}
return 1;
}

//gotoxy函数的实现,把光标移到到指定位置
void gotoxy(int x,int y)
{
COORD pos;
pos.X=y;
pos.Y=x;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}

//人物移动
void turn()
{
char c=getch();
switch(c)
{
case 'w':
//上面是空地或目的地
if(person_x-1>=0&&(map[person_x-1][person_y]==FLOOR||map[person_x-1][person_y]==DESTINATION))
{
map[person_x-1][person_y]+=PERSON;
map[person_x][person_y]-=PERSON;
person_x--;
}
//上面是箱子,再上面是空地或目的地
else if(person_x-2>=0&&(map[person_x-1][person_y]==BOX||map[person_x-1][person_y]==PERFECT)&&(map[person_x-2][person_y]==FLOOR||map[person_x-2][person_y]==DESTINATION))
{
map[person_x-2][person_y]+=BOX;
map[person_x-1][person_y]-=BOX;
map[person_x-1][person_y]+=PERSON;
map[person_x][person_y]-=PERSON;
person_x--;
}
break;
case 's':
//下面是空地或者目的地
if(person_x+1<row&&(map[person_x+1][person_y]==FLOOR||map[person_x+1][person_y]==DESTINATION))
{
map[person_x+1][person_y]+=PERSON;
map[person_x][person_y]-=PERSON;
person_x++;
}
//下面是箱子,再下面是空地或者目的地
else if(person_x+2<row&&(map[person_x+1][person_y]==BOX||map[person_x+1][person_y]==PERFECT)&&(map[person_x+2][person_y]==FLOOR||map[person_x+2][person_y]==DESTINATION))
{
map[person_x+2][person_y]+=BOX;
map[person_x+1][person_y]-=BOX;
map[person_x+1][person_y]+=PERSON;
map[person_x][person_y]-=PERSON;
person_x++;
}
break;
case 'a':
//左边是空地或者目的地
if(person_y-1>=0&&(map[person_x][person_y-1]==FLOOR||map[person_x][person_y-1]==DESTINATION))
{
map[person_x][person_y-1]+=PERSON;
map[person_x][person_y]-=PERSON;
person_y--;
}
//左边是箱子,再左边是空地或者目的地
else if(person_y-2>=0&&(map[person_x][person_y-1]==BOX||map[person_x][person_y-1]==PERFECT)&&(map[person_x][person_y-2]==FLOOR||map[person_x][person_y-2]==DESTINATION))
{
map[person_x][person_y-2]+=BOX;
map[person_x][person_y-1]-=BOX;
map[person_x][person_y-1]+=PERSON;
map[person_x][person_y]-=PERSON;
person_y--;
}
break;
case 'd':
//右边是空地或者目的地
if(person_y+1<col&&(map[person_x][person_y+1]==FLOOR||map[person_x][person_y+1]==DESTINATION))
{
map[person_x][person_y+1]+=PERSON;
map[person_x][person_y]-=PERSON;
person_y++;
}
//右边是箱子,再右边是空地或者目的地
else if(person_y+2<col&&(map[person_x][person_y+1]==BOX||map[person_x][person_y+1]==PERFECT)&&(map[person_x][person_y+2]==FLOOR||map[person_x][person_y+2]==DESTINATION))
{
map[person_x][person_y+2]+=BOX;
map[person_x][person_y+1]-=BOX;
map[person_x][person_y+1]+=PERSON;
map[person_x][person_y]-=PERSON;
person_y++;
}
break;
default:
break;
}
}

设计介绍

首先我们需要知道自己要做哪个关卡,我从网上搜了最简单的第一关。
其次呢我们需要给关卡的每个图片定义一个代号的数字,比如0表示空地,1表示墙壁,2表示箱子,4表示箱子需要推到的目的地,6(2+4)表示箱子推进目的地,5表示玩家,9(5+4)表示玩家进入了目的地。我们选取数字代号虽然说是任意的,但是要注意不能用一样的代号代表不同的图形(这里也是为啥目的地不选3的原因,选3的话,箱子进了目的地的结果是2+3=5,和玩家一样了)。当然大家可以根据自己喜好换别的数字当做玩家。
接下来我们按照代号将地图用一个二维数组表示(map[row][col]),并且设置好行列的宏定义(row,col)。
前期工作都准备好了,我们要开始设计游戏的逻辑实现了。我们先要把关卡内容展示出来,所以需要一个打印地图的函数(PrintMap());展示出来之后呢,玩家可以根据自己看到的关卡地图进行操作嘛,所以我们需要一个操作函数(turn());玩家每次操作完之后,都有可能已经通关了,所以我们需要一个判断玩家是否已经通关的函数(IsWin())。最后再把这几个函数拼凑在主函数中调用,这样一个简单的推箱子游戏就完成啦。如果想设置多层关卡,可以结合文件操作哦!先将地图信息都保存在文件中,将文件名设置为关卡名,如1.txt表示第一关的关卡内容。地图信息包括行、列、详细图形代号。在我们需要读取关卡时,只需要设置一个函数读取即可,然后需要将玩家的坐标计算出来,再进行以上操作。

设计总结

这个推箱子可以加深我们的二维数组应用经验,同时判断玩家移动的过程也让我们的逻辑思维能力得到了提高,对事情的多角度思考有莫大的帮助。
有兴趣的话还可以添加撤销功能,思路如下:每次玩家移动,都记录下来存在一个数组中(直接记录玩家的移动方向即可,当收到玩家的撤销请求时,先把地图还原为关卡初始状态,然后依次读入记录数组的移动方向,读取到倒数第二个即可,然后把数组的长度减一)。
对于添加关卡,我们还可以用到文件操作,加深文件操作的理解和运用能力。
总的来说,推箱子的设计可以多方面巩固我们的已有知识,甚至有的小伙伴想要设计让电脑自动推箱子的话,我们还得需要用到人工智能的知识,这样还会激发我们的求知欲。闲暇之余设计一下简单游戏,无疑是有百利而无一害的。
  • 点赞 1
  • 收藏
  • 分享
  • 文章举报
qq_36694133 发布了8 篇原创文章 · 获赞 3 · 访问量 310 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐