人人都可以用C语言写推箱子小游戏

栏目: C · 发布时间: 7年前

内容简介:C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了。这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游戏项目。GitHub 仓库地址:先来看看最后的运行的效果。

C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了。这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游戏项目。

GitHub 仓库地址: github.com/weizhiwen/C…

先来看看最后的运行的效果。

人人都可以用C语言写推箱子小游戏

这是一个在 Windows Dos 界面的小游戏,界面上有推箱子的地图,使用 # 来代表地图的边界, P 来代表推箱子的小人, X 来代表箱子, O 来代表箱子要推到的目标位置。

W(w)、S(s)、A(a)、D(d)分别对应小人向上、下、左、右移动。

要写这个小游戏,我们面临的问题有以下几个。

  • 1、游戏地图怎么保存?

  • 2、游戏怎么运行?

  • 3、游戏地图怎样在位置固定的情况下不断变化?

  • 4、小人的移动逻辑怎么写?

  • 5、游戏怎么结束?

1、游戏地图怎么保存?

C语言中只有基本的数据类型,游戏地图是二维的平面结构,很容易想到使用二维数组来保存游戏地图,代码详情见 GitHub 仓库中的 关卡.h 文件。

人人都可以用C语言写推箱子小游戏

2、游戏怎么运行?

因为推箱子游戏在游戏结束之前要不断接受用户的输入,所以我们可以设置一个标志来判断游戏是否结束,把这个标志设置为一个 while 循环的条件。在每次循环中,都要接收用户的输入,根据用户输入的值,来进行下一步的操作,在游戏中就是小人的移动方向,上下左右,这里我们可以用一个 switch 语句判断。每一次循环,对应一次用户输入。

3、游戏地图怎样在位置固定的情况下不断变化?

在每次循环中,首先要把当前的地图显示出来,便于用户下一次的移动输入。我们将游戏地图设置为一个全局变量,这样在小人移动后,地图上的字符改变就是永久的,然后打印局部改变的新地图。这样程序不断循环,一遍遍的打印地图,游戏地图上的字符是可以不断改变了,但是地图的位置并不能固定下来。如果我们能刷新界面上的值,不就可以在位置固定的情况下不断变化了。刷新本质就是除旧迎新,即把原来的除去,迎来新的。在程序中,我们可以把原来的界面清除,再把新的界面显示在原来的位置。C语言中可以用 system("cls") 函数来清除控制台的内容,然后我们再把新的地图内容显示出来。

小人的移动逻辑属于具体的程序实现,我们放到下面再说,先来说说程序怎么结束。

4、游戏怎么结束?

前面我们说设置一个标志来判断游戏是否结束,但是游戏什么时候结束呢?推箱子的游戏目标是将每个箱子推到目标位置,这是一种游戏结束的情况,由于每次循环都要判断,可以将其写成一个函数。另外,如果用户不想玩了想退出,这也是一种游戏结束的情况,这里我只考虑了这两种情况,至于其他情况,读者可自行考虑。

到目前位置我们可以写出程序大致的框架了,外部一个大循环,每次循环都是先刷新界面,接收用户输入,处理用户的输入,判断游戏是否结束。

人人都可以用C语言写推箱子小游戏

5、小人的移动逻辑怎么写?

在上面的程序截图中,可以看到我把小人的上下左右移动分别写到了四个函数中,分别是 MoveToUp()、MoveToDown()、MoveToLeft()、MoveToRight()。以 MoveToUp() 函数为例,我们来分析小人移动的逻辑。

理论上,小人是可以上下左右的移动的,但是,由于有地图的限制,小人不能穿墙的,只能在允许的道路上移动,比如下面这种情况,小人想向上移动,肯定是不允许的。

人人都可以用C语言写推箱子小游戏

而下面这种的情况,小人是可以向上移动的,因为小人上面一格并没有限制物。

人人都可以用C语言写推箱子小游戏

所以我们要对小人理论上可以移动到的那格(下一位置)进行判断,如果不是限制物(箱子和箱子要移动到的位置下面在详细说),小人就可以移动,如果有限制物就不能移动。所以我们需要记录一个坐标点的值,这里“下一位置”的参照物可以选取小人当前的位置,游戏开始时,把小人的开始位置作为当前位置。小人向上移动,“下一位置”的横坐标就是小人当前位置的横坐标减一,纵坐标就是小人当前位置的纵坐标。然后我们就可以根据“下一位置”的横纵坐标找到具体的字符值,如果是空的,就可以移动,如果是箱子要移动的目标位置,小人也可以移动,还有一种情况是“下一位置”是箱子,我们还要考虑箱子的“下一位置”,箱子的下一位置也很好得到。因为小人和箱子是在一条线上移动的,所以在小人向上移动时,箱子的“下一位置”的横坐标就是小人“下一位置”的横坐标减一,两者的纵坐标相同。同样我们也要对箱子“下一位置”的字符值进行判断,如果字符值是空格和箱子可以移动的位置,就是可以移动的。小人向上移动的代码如下:

人人都可以用C语言写推箱子小游戏

小人向下、向左、向右移动的代码也是类似的,无非就是把小人移动的下一坐标改一改,向下移动,“下一位置”的横坐标就是小人的横坐标位置加一,两者纵坐标相同,代码详情见 GitHub 仓库中的 控制.cpp 文件。

到这里整个程序就算是完成了,可以运行整个程序效果如下,能发现哪里有 Bug 吗?

人人都可以用C语言写推箱子小游戏

相信细心的你已经发现了,当小人移动到箱子要移动的目标位置,再移出,这个位置就会“消失”,为什么出现这种情况呢?我们在前面总是关注小人要移动的”下一位置“和箱子要移动的“下一位置”,却没有关注在移动之前,这个位置(上一位置)原本的值,我们可以记录这个“上一位置”的值,但是这样考虑的问题就比较多了,尤其是箱子和小人都在箱子要移动的目标位置时,情况很复杂,那么有木有简单的方法呢?其实到现在为止,我们的程序大体上是没什么问题的,只是箱子要移动的目标位置会出现“字符消失”。这只是个小 Bug,把用户当测试的微软是怎么做的呢?系统发行后不停的发布补丁,我们也可以像这样给这个程序打个“补丁”。箱子要移动的位置是不变的,我们可以能不能用一个二维数组来存放这些特殊位置呢?这些特殊位置的值也是特殊的,要不就是目标位置,要不就是箱子,要不就是小人,而不能是空白字符,所以我们可以写一个“补丁”——修复这个 Bug 的函数。当小人移动后,在每个方向的移动函数结尾加上下面这个修复函数。这里判断特殊位置是不是空白字符,如果是空白字符,就将特殊位置的值改为目标位置的字符值,这里是字符 “O”,这样就“修复”了程序的 Bug,“字符消失”的问题也被解决了。

人人都可以用C语言写推箱子小游戏

我将程序划分成了不同的文件,GitHub仓库也有程序目录的说明文件,读者在阅读代码时,会注意到 extern 关键字的使用,这个关键字是为了拆分的多个文件之间共用某个变量或者函数。将关卡中的游戏地图更换,就可以实现推箱子的多个关卡,读者有兴趣可自己尝试改进,本文也是起到一个抛砖引玉的作用。

最后想说的是,写程序很注重逻辑,无论用什么语言,程序的逻辑都是一样的,无非就是哪种语言更方便,更快捷。 写程序真正玩的是逻辑 ,只有逻辑清晰,代码才能写得好,否则顶多也是代码的搬运工。

欢迎关注我的微信公众号:“编程心路”,在编程的路上,我们一起成长,回复任意关键字会有惊喜哦!

人人都可以用C语言写推箱子小游戏

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python for Everyone

Python for Everyone

Cay S. Horstmann、Rance D. Necaise / John Wiley & Sons / 2013-4-26 / GBP 181.99

Cay Horstmann's" Python for Everyone "provides readers with step-by-step guidance, a feature that is immensely helpful for building confidence and providing an outline for the task at hand. "Problem S......一起来看看 《Python for Everyone》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器