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


c语言是许多程序员的入门语言,其重要性不言而喻,因为它奠定了许多编程习惯和逻辑思维的基础。我通过学习c语言,编写了一个推箱子小游戏,提升了我的逻辑能力。现在,我想与大家分享这个推箱子小游戏项目。

GitHub 仓库地址:https://www./link/9a66e987aff9a6d0f673189ca1e72f78

首先,让我们看一下游戏运行的最终效果。

最终的效果图

这是一个在 Windows Dos 界面下运行的小游戏,游戏界面上显示了推箱子的地图。其中,# 表示地图的边界,P 表示推箱子的小人,X 表示箱子,O 表示箱子需要推到的目标位置。

游戏操作使用 W(w)、S(s)、A(a)、D(d) 键,分别对应小人向上、下、左、右移动。

在编写这个小游戏时,我们面临了一些挑战:

  1. 如何保存游戏地图?

  2. 游戏如何运行?

  3. 如何在固定位置上不断更新游戏地图?

  4. 小人的移动逻辑如何实现?

  5. 游戏如何结束?

  6. 如何保存游戏地图?

    C语言只有基本的数据类型,而游戏地图是二维的平面结构。我们可以使用二维数组来保存游戏地图,具体代码可在 GitHub 仓库中的 关卡.h 文件中找到。

    游戏地图

  7. 游戏如何运行?

    由于推箱子游戏在结束前需要不断接收用户输入,我们可以设置一个标志来判断游戏是否结束,并将此标志设置为 while 循环的条件。在每次循环中,接收用户输入,根据输入值决定小人的移动方向(上下左右),这里可以使用 switch 语句来判断。每一次循环对应一次用户输入。

  8. 如何在固定位置上不断更新游戏地图?

    在每次循环中,首先显示当前的地图以便用户进行下一次移动。我们将游戏地图设置为全局变量,这样小人移动后,地图上的字符改变将是永久的,然后打印出局部改变的新地图。程序不断循环,一遍遍打印地图,使得地图上的字符可以不断改变,但地图的位置无法固定。我们可以通过刷新界面来实现这一点。刷新本质上是除旧迎新,即清除原来的界面,再显示新的界面。C语言中可以使用 system("cls") 函数清除控制台内容,然后再显示新的地图内容。

    小人的移动逻辑属于具体的程序实现,我们稍后再讨论,先来说说程序如何结束。

  9. 游戏如何结束?

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

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

    程序大致框架

  10. 小人的移动逻辑如何实现?

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

    理论上,小人可以上下左右移动,但由于有地图的限制,小人不能穿墙,只能在允许的道路上移动。例如,小人想向上移动,但如果上面一格有限制物(如墙),就不允许移动。

    不能向上移动

    而如果上面一格没有限制物,小人就可以向上移动。

    可以向上移动

    因此,我们需要对小人理论上可以移动到的位置(下一位置)进行判断。如果下一位置不是限制物(箱子和箱子要移动到的位置),小人就可以移动。如果有限制物,就不能移动。我们需要记录一个坐标点的值,游戏开始时,小人的初始位置作为当前位置。小人向上移动时,下一位置的横坐标就是小人当前位置的横坐标减一,纵坐标不变。然后根据下一位置的横纵坐标找到具体的字符值,如果是空的或目标位置,小人就可以移动。如果下一位置是箱子,我们还要考虑箱子的下一位置。由于小人和箱子在一条线上移动,小人向上移动时,箱子的下一位置的横坐标就是小人下一位置的横坐标减一,两者的纵坐标相同。同样,我们也要对箱子下一位置的字符值进行判断,如果是空格或箱子可以移动的位置,就可以移动。小人向上移动的代码如下:

    小人向上移动

    小人向下、向左、向右移动的代码类似,只需修改小人移动的下一坐标。向下移动时,下一位置的横坐标是小人的横坐标加一,纵坐标不变。具体代码请参见 GitHub 仓库中的 控制.cpp 文件。

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

    有Bug的效果图

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

    修复函数

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

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


# git  # windows  # github  # c语言  # switch  # win  # 微软  # 数据类型  # while  # extern  # 全局变量  # 循环  # https  # bug  # 下一  # 我们可以  # 推箱子  # 就可以  # 上下左右  # 可以使用  # 的是  # 多个  # 上一  # 我将 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: 如何在 Go 中正确反序列化多个同级 XML 元素(而非单个根节点)  Win11怎么设置任务栏图标大小_Windows11注册表TaskbarSi修改  Windows10怎么用“讲述人”读屏辅助 Windows10轻松使用开启讲述人朗读屏幕文字帮助视障用户【教程】  Win11开机Logo怎么换_Win11自定义启动画面工具【高级】  如何在Golang中编写异步函数测试_Golang异步操作测试策略  Win11怎么关闭自动调节亮度 Win11禁用内容自适应亮度【设置】  MySQL 中使用 IF 和 CASE 实现查询字段的条件转换  Windows 11怎么更改锁屏超时时间_Windows 11电源选项中设置屏幕关闭时间  PHP接收参数长度超限怎么办_修改postmaxsize设置教程【解答】  Python对象比较与排序_集合使用说明【指导】  LINUX怎么查看进程_LINUX ps命令查看运行服务  LINUX如何开放防火墙端口_Linux firewalld与iptables开放端口命令【安全配置】  Windows系统文件被保护机制阻止怎么办_权限不足错误处理方案  如何使用Golang实现Web表单数据绑定_自动映射字段到结构体  Win11怎么设置DNS服务器_Windows11修改网络适配器DNS优选  Win11此电脑不在桌面上_Windows 11桌面图标设置找回【步骤】  Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】  Windows10如何删除恢复分区_Win10 Diskpart命令强制删除分区  Win11怎么清理C盘下载文件夹_Win11清理下载文件夹技巧【教程】  Win11怎么设置ip地址_Windows 11手动配置网络IP教程【详解】  Win11局域网共享怎么设置 Win11文件夹网络共享教程【详解】  Win10如何更改开机密码_Windows10登录选项更改密码  Win11怎么清理C盘系统日志_Win11清理系统日志文件【步骤】  Win11怎么关闭内容自适应亮度_Windows11显示设置CABC关闭  php下载安装包太大怎么下载_分卷压缩下载方法【教程】  Win11怎么关闭应用权限_Windows11相机麦克风隐私管理  Win11怎么关闭自动调节亮度_Windows11禁用内容自适应亮度  Windows10如何更改鼠标图标_Win10鼠标属性指针浏览  c# 在高并发场景下,委托和接口调用的性能对比  Win11怎么设置鼠标宏_Win11鼠标按键自定义编程教程【详解】  MAC怎么用连续互通相机里的“桌上视角”_MAC在视频通话中同时展示人脸和桌面  如何用正则与预处理结合精准拦截拼接式垃圾域名  php下载安装后swoole扩展怎么安装_异步框架支持【汇总】  Windows7如何安装系统镜像_Windows7系统安装教程【步骤】  c++如何判断文件是否存在_c++ filesystem库用法  Windows11怎么自定义任务栏_Windows11任务栏自定义教程【步骤】  Win11如何设置自动关机 Win11定时关机命令使用教程【技巧】  Django 密码修改后会话失效的解决方案  如何在Golang中实现自定义Benchmark_Golang testing.B自定义性能测量示例  使用类变量定义字符串常量时如何实现类型安全的 Literal 注解  Python大文件处理策略_内存优化说明【指导】  Python邮件系统自动化教程_批量发送解析与模板应用  php中$this和::能混用吗_对象与静态作用域冲突解决【方法】  Django密码修改后会话失效的解决方案  Windows10怎么备份注册表_Windows10注册表备份步骤【教程】  php怎么下载安装后无法解析php文件_服务器配置检查【解答】  Win11怎么查看wifi信号强度_检测Windows 11无线网络质量方法【详解】  Windows怎样关闭Edge新标签页广告_Windows关闭Edge新标签页设置【步骤】  如何在 Pandas 中按元素交集合并两列字符串  php能跑在stm32上吗_php在stm32微控制器上的移植方法【介绍】 

 2025-09-25

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.