C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目
C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了。这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游戏项目。
GitHub 仓库地址:github.com/weizhiwen/C…
先来看看最后的运行的效果。
这是一个在 Windows Dos 界面的小游戏,界面上有推箱子的地图,使用#来代表地图的边界,P来代表推箱子的小人,X来代表箱子,O来代表箱子要推到的目标位置。
W(w)、S(s)、A(a)、D(d)分别对应小人向上、下、左、右移动。
要写这个小游戏,我们面临的问题有以下几个。
1、游戏地图怎么保存?
2、游戏怎么运行?
3、游戏地图怎样在位置固定的情况下不断变化?
4、小人的移动逻辑怎么写?
5、游戏怎么结束?
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,“字符消失”的问题也被解决了。
我将程序划分成了不同的文件,GitHub仓库也有程序目录的说明文件,读者在阅读代码时,会注意到extern关键字的使用,这个关键字是为了拆分的多个文件之间共用某个变量或者函数。将关卡中的游戏地图更换,就可以实现推箱子的多个关卡,读者有兴趣可自己尝试改进,本文也是起到一个抛砖引玉的作用。
最后想说的是,写程序很注重逻辑,无论用什么语言,程序的逻辑都是一样的,无非就是哪种语言更方便,更快捷。写程序真正玩的是逻辑,只有逻辑清晰,代码才能写得好,否则顶多也是代码的搬运工。
作者:Wizey
原文链接:https://juejin.im/post/5b874d4551882542ee71761b
自学C/C++编程难度很大,不妨和一些志同道合的小伙伴一起学习成长!
C语言C++编程学习交流圈子,【点击进入】微信公众号:C语言编程学习基地
有一些源码和资料分享,欢迎转行也学习编程的伙伴,和大家一起交流成长会比自己琢磨更快哦!
C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目的更多相关文章
- 每个人都可以用C语言写的推箱子小游戏!今天你就可以写出属于自己项目~
C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...
- 完整版本的推箱子小游戏,最简单的纯C语言打造
/* 推箱子小游戏 1.定义绘制样式 用二维数组的方式 2.绘制图像 3.找出当前位置 4.逻辑判断,制造动作 根据数学xy轴的规律,这里使用ij 上移,行轴上升,行数减少 下移,行数下降,函数增加 ...
- 推箱子小游戏《格鲁的实验室》13关 - bfs最短路径
下载了一款推箱子小游戏,第13关的时候怎么也破不了最佳纪录(最少步数是9而我们最好的方案是10步),因为数据比较小(6*8的方阵),所以写了个BFS来找最短路. 游戏的目标是把小黄人推到黄色球,小绿人 ...
- C++ 控制台推箱子小游戏
// 游戏菜单.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #in ...
- C语言写的2048小游戏
基于"基于C_语言的2048算法设计_颜冠鹏.pdf" 这一篇文献提供的思路 在中国知网上能找到 就不贴具体内容了 [摘 要] 针对2048的游戏规则,分析了该游戏的算法特点,对其 ...
- c++、c实现推箱子小游戏
经过四次的修改和优化,终于将推箱子这个游戏完整的写出来了,今天就像大家分享一下这个游戏的编写. 这个游戏界面的编写总的来说不困难,主要是推动箱子的算法. (1)利用数组和windows api 即可写 ...
- 用C#制作推箱子小游戏
思路分析: 一.制作一个地图 二.地图中放置墙.箱子.人.目标等 三.让小人动起来完成推箱子动作 游戏制作: 1.按照上述地图制作一个地图 (12行×13列) 地图可以看做是行和列组成的,即可以看做 ...
- C语言实现推箱子游戏完整代码
C语言实现推箱子游戏完整代码 前言 自己做的,可能有些代码不够工整,或者有些小问题,但游戏的基本操作是可以实现的 代码效果 代码一共分为8个部分,4个控制上下左右移动,2个判断输赢,1个统计归为的个数 ...
- 2048小游戏代码解析 C语言版
2048小游戏,也算是风靡一时的益智游戏.其背后实现的逻辑比较简单,代码量不算多,而且趣味性强,适合作为有语言基础的童鞋来加强编程训练.本篇分析2048小游戏的C语言实现代码. 前言 游戏截图: 游 ...
随机推荐
- mysql中给查询结果添加序号
当我们想为查询结果添加序号的时候可以这样写 SELECT @rowid:=@rowid+1 allid, pan_number, receive_person,time_note, url,unit_ ...
- 华为云MVP熊保松谈物联网开发:华为云IoT是首选,小熊派是神器
摘要:在AI.5G的技术驱动下,物联网行业的发展愈加如火如荼,开发者在技术的快速更迭间,也得乘风破浪跟上新技术的节奏. 在AI.5G的技术驱动下,物联网行业的发展愈加如火如荼,开发者在技术的快速更迭间 ...
- day79 组件化开发
目录 一.组件[component] 默认组件 二. Vue自动化工具(Vue-cli) 1 安装node.js 2 npm 3 安装Vue-cli 4 使用Vue-CLI初始化创建前端项目 4.1 ...
- 07 Vue常见插件
项目功能插件 1.vue-router { path: '/', name: 'home', // 路由的重定向 redirect: '/home' } { // 一级路由, 在根组件中被渲染, 替换 ...
- CTF_show平台 web题解 part3
web13 题目显示文件上传,各类型上传均提示错误,在使用ctf-scan扫描的时候,发现upload.php.bak. 查看源码: <?php header("content-typ ...
- 数据可视化之powerBI基础(七)一文带你熟悉PowerBI建模视图中的功能
https://zhuanlan.zhihu.com/p/67316729 PowerBI 3月的更新,正式发布了建模视图,而之前只是预览功能.新的建模视图到底有什么用,下面带你认识一下它的主要功能. ...
- Thymeleaf模板引擎学习
开发传统Java WEB项目时,我们可以使用JSP页面模板语言,但是在SpringBoot中已经不推荐使用JSP页面进行页面渲染了.从而Thymeleaf提供了一个用于整合Spring MVC的可选模 ...
- 如何写一个自己的HashMap
想必很多Java工程师出去面试的时候都会被问到HashMap的底层实现原理,很多人觉得没什么必要,反正我会用就行,就我的感觉而言,在初期确实没什么必要,但是站在公司角度想,如果面试者连底层实现都搞定了 ...
- 年薪30W+高薪测试技术要掌握哪些?
职业技能一 1. 软件测试: 1) 熟练灵活地运用等价类.边界值.判定表法.因果图法等各种方法设计测试用例,包括单元测试.集成测试.系统测试用例设计. 2) 牢固掌握了软件测试计划.测试日报.测试报告 ...
- Web Scraping using Python Scrapy_BS4 - using Scrapy and Python(1)
Create a new Scrapy project first. scrapy startproject projectName . Open this project in Visual Stu ...