C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目

C语言,做为大多数人的第一门编程语言,重要性不言而喻,不少编程习惯,逻辑方式在此时就已经造成了。这个是我在大一学习 C语言 后写的推箱子小游戏,本身的逻辑能力获得了提高,在这里同你们分享这个推箱子小游戏项目。git

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

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

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

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

要写这个小游戏,咱们面临的问题有如下几个。框架

一、游戏地图怎么保存?编程语言

二、游戏怎么运行?函数

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

四、小人的移动逻辑怎么写?学习

五、游戏怎么结束?

一、游戏地图怎么保存?

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

二、游戏怎么运行?

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

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

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

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

四、游戏怎么结束?

前面咱们说设置一个标志来判断游戏是否结束,可是游戏何时结束呢?推箱子的游戏目标是将每一个箱子推到目标位置,这是一种游戏结束的状况,因为每次循环都要判断,能够将其写成一个函数。另外,若是用户不想玩了想退出,这也是一种游戏结束的状况,这里我只考虑了这两种状况,至于其余状况,读者可自行考虑。

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

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

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

理论上,小人是能够上下左右的移动的,可是,因为有地图的限制,小人不能穿墙的,只能在容许的道路上移动,好比下面这种状况,小人想向上移动,确定是不容许的。

而下面这种的状况,小人是能够向上移动的,由于小人上面一格并无限制物。

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

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

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

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

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

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

做者:Wizey

原文连接:https://juejin.im/post/5b874d4551882542ee71761b


自学C/C++编程难度很大,不妨和一些志同道合的小伙伴一块儿学习成长!

C语言C++编程学习交流圈子,【点击进入微信公众号:C语言编程学习基地

有一些源码和资料分享,欢迎转行也学习编程的伙伴,和你们一块儿交流成长会比本身琢磨更快哦!

相关文章
相关标签/搜索