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

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

 

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

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

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

✿  游戏地图怎么保存?

✿  游戏怎么运行?

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

✿  小人的移动逻辑怎么写?

✿  游戏怎么结束?

1、游戏地图怎么保存?

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

 

2、游戏怎么运行?

因为推箱子游戏在游戏结束之前要不断接受用户的输入,所以我们可以设置一个标志来判断游戏是否结束,把这个标志设置为一个 while 循环的条件。

在每次循环中,都要接收用户的输入,根据用户输入的值,来进行下一步的操作,在游戏中就是小人的移动方向,上下左右,这里我们可以用一个 switch 语句判断。

每一次循环,对应一次用户输入。

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

在每次循环中,首先要把当前的地图显示出来,便于用户下一次的移动输入。

我们将游戏地图设置为一个全局变量,这样在小人移动后,地图上的字符改变就是永久的,然后打印局部改变的新地图。

这样程序不断循环,一遍遍的打印地图,游戏地图上的字符是可以不断改变了,但是地图的位置并不能固定下来。

如果我们能刷新界面上的值,不就可以在位置固定的情况下不断变化了。刷新本质就是除旧迎新,即把原来的除去,迎来新的。

在程序中,我们可以把原来的界面清除,再把新的界面显示在原来的位置。

C语言中可以用 system("cls") 函数来清除控制台的内容,然后我们再把新的地图内容显示出来。

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

4、游戏怎么结束?

前面我们说设置一个标志来判断游戏是否结束,但是游戏什么时候结束呢?

推箱子的游戏目标是将每个箱子推到目标位置,这是一种游戏结束的情况,由于每次循环都要判断,可以将其写成一个函数。

另外,如果用户不想玩了想退出,这也是一种游戏结束的情况,这里我只考虑了这两种情况,至于其他情况,读者可自行考虑。

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

 

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

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

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

 

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

 

所以我们要对小人理论上可以移动到的那格(下一位置)进行判断,如果不是限制物(箱子和箱子要移动到的位置下面在详细说),小人就可以移动,如果有限制物就不能移动。

所以我们需要记录一个坐标点的值,这里“下一位置”的参照物可以选取小人当前的位置,游戏开始时,把小人的开始位置作为当前位置。

小人向上移动,“下一位置”的横坐标就是小人当前位置的横坐标减一,纵坐标就是小人当前位置的纵坐标。

然后我们就可以根据“下一位置”的横纵坐标找到具体的字符值,如果是空的,就可以移动,如果是箱子要移动的目标位置,小人也可以移动,还有一种情况是“下一位置”是箱子,我们还要考虑箱子的“下一位置”,箱子的下一位置也很好得到。

因为小人和箱子是在一条线上移动的,所以在小人向上移动时,箱子的“下一位置”的横坐标就是小人“下一位置”的横坐标减一,两者的纵坐标相同。同样我们也要对箱子“下一位置”的字符值进行判断,如果字符值是空格和箱子可以移动的位置,就是可以移动的。

小人向上移动的代码如下:

 

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

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

 

相信细心的你已经发现了,当小人移动到箱子要移动的目标位置,再移出,这个位置就会“消失”,为什么出现这种情况呢?

我们在前面总是关注小人要移动的”下一位置“和箱子要移动的“下一位置”,却没有关注在移动之前,这个位置(上一位置)原本的值,我们可以记录这个“上一位置”的值,但是这样考虑的问题就比较多了,尤其是箱子和小人都在箱子要移动的目标位置时,情况很复杂,那么有木有简单的方法呢?

其实到现在为止,我们的程序大体上是没什么问题的,只是箱子要移动的目标位置会出现“字符消失”。这只是个小 Bug,把用户当测试的微软是怎么做的呢?系统发行后不停的发布补丁,我们也可以像这样给这个程序打个“补丁”。

箱子要移动的位置是不变的,我们可以能不能用一个二维数组来存放这些特殊位置呢?

这些特殊位置的值也是特殊的,要不就是目标位置,要不就是箱子,要不就是小人,而不能是空白字符,所以我们可以写一个“补丁”——修复这个 Bug 的函数。当小人移动后,在每个方向的移动函数结尾加上下面这个修复函数。

这里判断特殊位置是不是空白字符,如果是空白字符,就将特殊位置的值改为目标位置的字符值,这里是字符 “O”,这样就“修复”了程序的 Bug,“字符消失”的问题也被解决了。

 

我将程序划分成了不同的文件,读者在阅读代码时,会注意到 extern 关键字的使用,这个关键字是为了拆分的多个文件之间共用某个变量或者函数。

将关卡中的游戏地图更换,就可以实现推箱子的多个关卡,读者有兴趣可自己尝试改进,本文也是起到一个抛砖引玉的作用。

最后想说的是,写程序很注重逻辑,无论用什么语言,程序的逻辑都是一样的,无非就是哪种语言更方便,更快捷。

写程序真正玩的是逻辑,只有逻辑清晰,代码才能写得好,否则顶多也是代码的搬运工。

看到这里是不是又学到了很多呢~

如果你很想学编程,小编推荐的C语言/C++编程学习基地【点击进入】!

都是学编程小伙伴们,带你入个门还是简简单单啦,一起学习,一起加油~

还有许多学习资料和视频,相信你会喜欢的!

涉及:游戏开发、常用软件开发、编程基础知识、课程设计、黑客等等......

 

每个人都可以用C语言写的推箱子小游戏!今天你就可以写出属于自己项目~的更多相关文章

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

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

  2. 完整版本的推箱子小游戏,最简单的纯C语言打造

    /* 推箱子小游戏 1.定义绘制样式 用二维数组的方式 2.绘制图像 3.找出当前位置 4.逻辑判断,制造动作 根据数学xy轴的规律,这里使用ij 上移,行轴上升,行数减少 下移,行数下降,函数增加 ...

  3. canvas写个简单的小游戏

    之前在HTML5 Canvas属性和方法汇总一文中,介绍过Canvas的各种属性以及方法的说明,并列举了自己写的一些Canvas demo,接下来开始写一个简单的小游戏吧,有多简单,这么说吧,代码不到 ...

  4. 用canvas写个接水管小游戏

    声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢! 过年的十八天假期迷迷糊糊一下子就过去了(LZ还是实习生,鉴于大学最后一个寒假了,所以就多请了好多天假),又要返工上班了.这是年后的第一篇博 ...

  5. C语言-纸牌计算24点小游戏

    C语言实现纸牌计算24点小游戏 利用系统时间设定随机种子生成4个随机数,并对4个数字之间的运算次序以及运算符号进行枚举,从而计算判断是否能得出24,以达到程序目的.程序主要功能已完成,目前还有部分细节 ...

  6. python写的battle ship小游戏 - 1.0

    最近学python,这是今天写的一个小游戏. from random import randint class Board(object): board = [] def __init__(self, ...

  7. C 语言实例 - 约瑟夫生者死者小游戏

    30 个人在一条船上,超载,需要 15 人下船. 于是人们排成一队,排队的位置即为他们的编号. 报数,从 1 开始,数到 9 的人下船. 如此循环,直到船上仅剩 15 人为止,问都有哪些编号的人下船了 ...

  8. 利用c语言做简单的迷宫小游戏

                       #include <stdio.h> #define ROW 6 #define COL 6 // 封装打印地图的函数 void printMap(c ...

  9. 发个2012年用java写的一个控制台小游戏

    时间是把杀狗刀 突然发现了12年用java写的控制台玩的一个文字游戏,有兴趣的可以下载试试哈汪~ 里面难点当时确实遇到过,在计算倒计时的时候用了多线程,当时还写了好久才搞定.很怀念那个时间虽然不会做游 ...

随机推荐

  1. vue项目前端导出word文件(bug解决)

    摘要:之前项目中导出价格表是由后端实现,前端只需要调用接口下载word即可,后来业务改变比较大,word模版需要一直改动,后端改起来相对麻烦,后来直接前端自己定义模版,实现下载word文档. 一.需要 ...

  2. Promise核心实现

    核心 构造函数核心 维护状态变量,只能由pending变为resolve或者reject 维护一个存储结果的变量 维护一个回调数组,执行到then,如果我们传入的立即执行函数没有立即执行resolve ...

  3. oracle之三rman 不完全恢复

    rman 不完全恢复 9.1 rman 不完全恢复的三个标准模式:基于time.基于scn和基于sequence: 范例1:恢复过去某个时间点误操作,一般使用基于time或scn. 1)环境:有一套全 ...

  4. 【LeetCode/LintCode】丨Google面试题:N皇后问题

    n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击(任意两个皇后不能位于同一行,同一列,同一斜线). 给定一个整数n,返回所有不同的n皇后问题的解决方案. 每个解决方案包含一个明确的 ...

  5. CEO的行为风格会影响公司业绩吗?

    中国的两大互联网巨头--腾讯和阿里,创始人的风格非常不同.在公众面前,马云的形象是高谈阔论,而马化腾则显得较为低调.在公司管理上,马云不插手具体事务,而是站在高处务虚,抓战略.抓文化,而马化腾则是腾讯 ...

  6. 接口、RESTful规范、DRF

    接口 #接口:url连接,通过向链接发送不同的类型请求与参数得到相应的响应数据 #1.在视图书写处理请求的 视图函数 #2.在路由层为视图函数配置 url链接=>产生接口 #3.前台通过ajax ...

  7. 使用Scrcpy实现电脑控制安卓手机

    很多时候我们想要在电脑上使用一些手机软件,使用模拟器当然是一种选择,但是这些模拟器要不然不免费,要不然广告多不放心.Scrcpy是一个开源免费的软件,通过abd命令实现了安卓手机投屏和控制功能,并且支 ...

  8. 2020年秋季最新Python详细入门教程!全网最新最全

    1. import # -*- coding: utf-8 -*- ## 引入新的包 import turtle import pickle # 文件操作 import tensorflow as t ...

  9. UCanCode发布升级E-Form++可视化源码组件库2020全新版 !

    2020年. 中国.成都 UCanCode发布升级E-Form++可视化源码组件库2020全新版 ! --- 全面性能提升,UCanCode有史以来最强大的版本发布! E-Form++可视化源码组件库 ...

  10. 手把手教你在 TKE 集群中实现简单的蓝绿发布和灰度发布

    概述 如何在腾讯云 Kubernetes 集群实现蓝绿发布和灰度发布?通常要向集群额外部署其它开源工具来实现,比如 Nginx Ingress,Traefik 等,或者让业务上 Service Mes ...