900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 解析《啊哈C》--最终章:用C语言制作走迷宫和推箱子的小游戏

解析《啊哈C》--最终章:用C语言制作走迷宫和推箱子的小游戏

时间:2022-08-26 18:07:25

相关推荐

解析《啊哈C》--最终章:用C语言制作走迷宫和推箱子的小游戏

啊哈C语言:第8章 《游戏时间到了》-----/4/10

从2月底开始直到前天,当我学完二维字符数组、字典序后,翻到这一章的页面时,心情是欢喜的,我想一件坚持了很久的事情做到了最后关头,都是付出的时间、精力的成果!开心心!

而一个多月坚持独立思考的成果终于要检验了!相对于之前写过的程序,一个具有可操作性可玩性的游戏,是一种更加具象化的成果体现,也更加有成就感!!

下面就是正文啦!

快速抵达

@[TOC](快速抵达)推 箱 子***以上是推动单个O!!***

第一个游戏:走迷宫!

使用井号‘#’制作迷宫的宫墙,将大写字母‘O’当作小球,作为玩家操作的对象,右侧宫墙有一处缺口是终点,通过W S A D四个按键分别控制小球进行上、下、左、右的移动。

玩法是进入游戏操作小球从起始位置移动到终点即为游戏胜利。

迷宫主体全部使用 ‘ # ’组成,井号在C语言中属于字符,这让我们联想到使用一行行的字符串打印迷宫。那就是多行字符,所以应该要用上一章刚学的二维字符数组来打印这个地图!

观察地图的行列,一共有20行30列,每行字符串末尾有一个结束标记,所以定义二维字符数组a为:char a[20][31] ……后面按照迷宫的结构,初始化迷宫,每行无 # 处用空格键隔开,注意每行细节不能错。

效果如下:

char a[50][50]={"##############################","#O # ## # ### ####","# ###### # # # # # ### ####","# # ## # # #### # ### ##","# # ## ### # # ## ####","##### ## ##### ## ####","# # ##### # # # # # #","# # # ## # #### ## # # ####","# # # ##### # ####","# # # ####### ## ###### # ##","# # ## # ## ###### ### #","# ###### # ##### # # #","# # ###### ### # ","# ######## ##### # ### ### # #","## ## ##### ### ###","##### # ## ######### # #","## ## ## ### # #","# # ### ###### ####### #","# # ### ### #","##############################"};

注意字符串从0开始计数。之所以定义51行49列,因为方便。

而地图本身的20行30列准确定义为 a [19] [30] 中 20是行X表示20行,30是

列Y表示30列。

故理解行列为XY后,我们利用a [x] [y] 可以通过x、y来表示地图中任意位置。

故小球O 的位置是a[1][1],终点出口的位置是a[12][30]

故我们使用x=1;y=1存储小球起始位置,p=12;g=30存储终点位置

提前定义完xypg的值,还需要一个 i 来控制输出地图的for循环。

int i,x,y,p,q;char ch;x=1;y=1;p=12;q=30;

主要操作是控制小球移动,WASD四个按键,本质其实是输入字符WASD,所以每个循环最开始都是使用输入语句getch获取输入的字符。故应当定义一个字符变量ch来存储输入的字符。

先清屏,然后输出地图。紧接着进while循环,循环条件为1死循环。

获取字符后,用if语句判断输入的是什么字符。

for(i=0;i<=20;i++)puts(a[i]);while(1){ch=getch();//【输入语句】if(ch=='s')//【判断输入的字符是什么】

下面是最关键的两个内容,如何控制小球O规避宫墙 # ?以及小球O是怎么移动的呢?

我们之前理解过X和Y了,所以我们明白x+1,实际上就是增进一行!而y+1则是增进1列!xy代表着小球的位置,小球位于x行y列,故小球向左走,是

y-1,向右走是y+1,向上是x-1,向下是x+1!

一:检测用户输入了什么字符,进入了哪个if语句后,立刻开始检测“前方”是否为宫墙 # 若是则中断接下来的语句直接进入下个循环。该输入无效。

二:小球的移动过程是:原位置赋为空格——x或y值加1或减1——新位置赋为小球O

if(ch=='s'){if(a[x+1][y]!='#'){a[x][y]=' ';x++; //想想为什么不是a[x+1][y]呢?a[x][y]='O';}}

知晓了一个方向的操作,那么其他方向的操作都是相通的。

if(ch=='s'){if(a[x+1][y]!='#'){a[x][y]=' ';x++;a[x][y]='O';}}if(ch=='w'){if(a[x-1][y]!='#'){a[x][y]=' ';x--;a[x][y]='O';}}if(ch=='a'){if(a[x][y-1]!='#'){a[x][y]=' ';y--;a[x][y]='O';}}if(ch=='d'){if(a[x][y+1]!='#'){a[x][y]=' ';y++;a[x][y]='O';}}

重点基本就结束啦,是不是还缺了点什么?

最后还要检测小球是否到了终点,如果是,就跳出循环并庆祝用户游戏通关!

如果不是,就重新清屏并输出一遍地图,对于已经变动过的xy值,这相当于刷新。

system("cls");for(i=0;i<=20;i++)puts(a[i]);if(x==p&&y==q)break;while(1)printf("%s牛逼!",u);Sleep(3000);return 0;

游戏结束,开头让用户输入个名字,储存起来庆祝的时候用就好啦!

效果可喜庆了!

其实这个游戏十分简单,只要理解了二维字符数组有关位置的概念就什么都知道了。

推 箱 子

本章的第二个游戏,也是最后一个游戏,亦是本书最后一个程序

如果说走迷宫游戏是一瓶矿泉水,那么推箱子游戏就是一瓶果粒橙橙汁!

它建立在走迷宫的基础之上,所以我在详述完走迷宫后,关于推箱子的部分,就仅剖析最关键最重要的部分!

如上图所示,推箱子游戏的玩法和走迷宫相似,WASD控制小人S上下左右移动。不同的是,增加了小人S推动箱子O的节目。

char u[11];gets(u);char a[7][11]={"##########","#####","##O### #","# S O O #","# !!# O ##","##!!# ##","##########",};

以上是地图

控制S推动O,直至四个箱子O都被推至四个感叹号处,游戏通关!

这个游戏最核心最关键的重点在于:

如何用WASD控制S上下左右移动S如何规避宫墙(S前方为墙时,推动无效)S如何推动1个箱子OS如何推动多个箱子OS推动一个或多个箱子O时,如何让箱子O规避宫墙(也就是O前方为墙时S的推动无效)

1和2在走迷宫里已经解读过了

规避的宫墙

if(nb=='w'){if(a[x-1][y]!='#')

S向上移动

a[x][y]=' ';x--;a[x][y]='O';

O也是字符,让S动起来的原理也是让O动起来的原理。

关键在于O和S如何协同移动!

当S移动的方向上没有O时,S仅移动自己;当S移动的方向上有O时,推动O并移动自己!

这是一个分支选项,可以用 if 分支来判断这个问题。

输入某个按键,进入某个按键的 if 的循环时,首先应当判断前方是否为宫墙。紧接着就是判断前方是否有O!

当我们单单移动S时,我们是:原位置赋空格—朝方向进1或退1—新位置赋S

我们先回顾一下规避宫墙:倘若S前方为宫墙#,S如此操作的话,宫墙 # 会被S吞掉!

这就是当我按下W后,为什么使用if(a[x-1][y]!='#')作为最外的 if 嵌套。来规避宫墙

故当我们对箱子O也是一个心思时,我们不想要S吞掉O,故操作S的步骤要放到【判断前方不是箱子O】这个语句内。

if(a[x-1][y]!='O')

故S前方不是O才能移动,那么S和O之间进行协同移动时,应当是O先动,S再动!

所以操作顺序明确了,先O后S。

按下某个键,进入某个if内,先判断宫墙,然后进入O的操作:

1.判断O前方是否是宫墙#

2. 如果不是就操作O向前!

以上是推动单个O!!

但是多个O呢?如何推动多个箱子?

箱子数量是未知的!故我们应当要计数

我们利用for循环,统计前方是否有O,控制for循环的整型变量 j 初始值是0,当确认前方有O时为1,进入for循环,倘若前方还有O则 j+1 并继续循环,直至前方不为O时跳出循环

此时 j 的值便是S前方的小球O的数量

我们要判断最后一个小球前方是不是宫墙 # 如果是,就不能执行推动O了

if(a[x-(j+1)][y]!='#')//【最后一个球的下一位是否是墙】

以下就是完整的一段:如何操作S推动1个或多个小球

if(nb=='w'){if(a[x-1][y]!='#'){if(a[x-1][y]=='O'){j++;while(1){if(a[x-(j+1)][y]=='O')//【统计有多少个球】j++;elsebreak;}if(a[x-(j+1)][y]!='#')//【最后一个球的下一位是否是墙】{while(j>=1)//【从后往前,逐步操作小球直到最后一个小球】{a[x-j][y]=' ';a[x-(j+1)][y]='O';j--;}}}if(a[x-1][y]!='O')//【验证了前方无小球后,移动S】{a[x][y]=' ';x--;a[x][y]='O';}}}

本章是《啊哈C语言》的最终章,其实走迷宫这个例子用的非常好,推箱子这个游戏用的更妙。做完这俩游戏,学生也算是出炉了!

走迷宫游戏,作者在书中从头到尾讲了一遍。

而对于推箱子游戏,作者在介绍完游戏玩法后,便宣布本书内容的结束!

这是最骚的!

纪磊老师将这最后的程序交给了读者,他引导读者依靠自己的实力完成这个游戏,只有依靠独立思考解决的问题,才是最有成就感的!也才能激起对编程的兴趣!

全书中纪磊老师一直在引导读者培养独立思考的意识!直到最后,也映射着编程之路都是独立思考为先!

。。。码了两个小时有点累,感谢纪磊老师贡献的这本书!纪念我在这本书中,每一个逻辑挑战中,成功运行程序时,所收获的纯粹的快乐!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。