用C写一个简单的推箱子游戏(一)
我现在在读大二,我们有一门课程叫《操作系统》,课程考查要求我们可以写一段程序或者写Windows、iOS、Mac的发展历程。后面我结合网上的资料参考,就想用自己之前简单学过的C写一关的推箱子小程序。
这一程序主要用到了C语言中的二维数组,头文件#include<conio.h>(因为要调用getch()函数以记录输入内容),switch函数等。
一、 功能概述
a) 游戏规则概述
玩家通过键盘输入W、S、A、D四键或者“↑”、“↓”、“←”、“→”四个方向键推动箱子,而箱子只可以推, 不可以拉, 而且一次只能推动一个,胜利条件就是把所有的箱子都推到目的地。
b) 需要实现的功能
1) 能够实现键盘操作功能:能够接收到键盘输入的方向键信息,并根据不同的方向键把游戏任务移动到相应的位置。例如,当玩家单击方向键“↑”时,如果向上的位置是可移动的,那么就当把游戏人物向上移动一个方格;
2) 能够判断人物能否移动:比如说人旁边是墙壁时是不能移动的,不能出现“人穿墙”的现象。人也不能同时推动两个箱子,因此要判断箱子的前方的情况;
3) 能够判断游戏结果:在玩家将所有的箱子推到对应的位置以后,能够打印出“恭喜你,你赢了!”的结果。由于这个游戏并没有设置时间限制,也没有设置所能走的步数限制,因此,只要玩家有兴趣玩下去,那么直到他将所有的箱子推进指定地点之前花了多少时间和步数都无所谓,只有将所有的箱子推进指定地点之后,才算赢了。
4) 优化游戏体验:因为图形化界面难做,简单的图案可能玩家看不懂,所以在游戏区域上方可以加上“温馨提示”字样,让玩家能够很容易地明白游戏界面各图案表示的是什么意思,比如如下表示方法:■:墙;♀:人;☆:箱子;◎:终点;♂:人在终点。
二、 程序总体模块分析
本程序总体大致可分为三大模块,即读入、判断调整、输出:
a) 读入:即设置读入操作把使用者的输入操作符读入程序,并定义变量储存起来为下一步的判断做好准备;
b) 判断调整:这一操作为下一步的调整二维数组内容提供依据,通过大量的判断语句对所有可能出现的情况提供相对应的唯一操作,使用户能顺利使用软件并起到规范化输入的目的——当输入不明字符时不作处理。判断结束后,执行相应操作改变数组内容从而改变输出内容,使用户顺利进行下一步操作;
c) 输出:通过刷屏后重新输出从而使游戏界面得以改变(比如人物移动、箱子移动、箱子状态改变等),进而等待用户下步的输入操作。
三、 程序关键代码介绍
a) 头文件#include<conio.h>与getch()函数
根据流程图和功能需要的分析可知,程序要求要能够实现键盘操作功能,即能够接收到键盘输入的方向键信息,并根据不同的方向键把游戏任务移动到相应的位置。因此,需要接收玩家指令。所以需要使用getch()函数以作记录键盘输入内容。
b) 绘制二维地图

“推箱子”游戏有很多关卡,这里只设计了一个关卡,要增加更多关卡可以继续进行绘制,采用三维数组,其中一组记录关卡数即可,此处为简便起见,只设计了一个关卡,关卡绘制的二维地图如上图所示。其中,■表示墙;♀表示人;☆表示箱子;◎表示终点;♂表示人在终点;★表示箱子位于终点。
在程序代码中,绘制二维地图采用二维数组的方式(因为这里只有一个关卡,就没有使用三维数组)。绘制二维地图采用的二维数组函数如下:
1 int map[9][11]=
2 {
3 {0,1,1,1,1,1,1,1,1,1,0},
4 {0,1,0,0,0,1,0,0,0,1,0},
5 {0,1,0,0,3,0,0,0,0,1,0},
6 {0,1,0,3,0,3,3,3,0,1,1},
7 {0,1,0,0,0,2,0,0,0,0,1},
8 {1,1,0,0,1,1,1,0,3,0,1},
9 {1,0,4,4,0,4,0,0,0,0,1},
10 {1,0,4,4,0,4,4,3,0,1,1},
11 {1,1,1,1,1,1,1,1,1,1,0}
12 };
其中 0 代表着空白的地方; 1 代表着墙;2 代表着人;3 代表着箱子;4 代表着箱子的终点位置。因为地图为9行11列,所以map函数的两个数组值为[9][11]。
c) 主函数主要内容
1 while(1)
2 {
3 system("cls");
4 printf("温馨提示:\n■:墙;\n♀:人;\n☆:箱子;\n◎:终点;\n♂:人在终点;\n★:箱子位于终点\n游戏制作者圣波祝您游戏愉快\n\n");
5 drawmain();
6 tuidong();
7 }
说明:
1) 因为界面需要随着人的移动而刷新,所以要使用循环结构并采用清屏函数system("cls")进行实时刷新;
2) 对玩家界面要友好,因此,用printf将提示信息打印在屏幕上,方便玩家理解游戏界面;
3) drawmain()函数是对游戏二维地图的绘制,将代码中的界面用图形展示出来;
4) tuidong()函数是对玩家输入的情况进行判断,通过判断键入的字符对游戏人物进行移动,并要判断人物前方的情况,从而判断人物能否移动,这是该游戏程序中最重要的部分,也是最难的一个部分。
d) drawmain()函数:二维地图的绘制
1 int i,j;
2 winshu();//调用输赢的函数(解释见f部分)
3 for(i=0;i<9;i++)
4 {for(j=0;j<11;j++)
5 {switch(map[i][j])
6 {case 0: printf(" "); //空白的地方
7 break;
8 case 1: printf("■"); //墙
9 break;
10 case 2: printf("♀"); //人
11 break;
12 case 3: printf("☆"); //箱子
13 break;
14 case 4: printf("◎"); //终点地方
15 break;
16 case 6: printf("♂");//人加终点位置
17 break;
18 case 7: printf("★") ;//箱子加终点位置
19 break; }}
20 printf("\n");}
说明:
1) 为了在图的上方显示结果,所以在打印二维地图前调用判断输赢的函数;
2) 利用switch()函数,将二维数组中的数字转化为屏幕中的图形界面。
tuidong()及以后的函数请看后一篇随笔《用C写一个简单的推箱子游戏(二)》
用C写一个简单的推箱子游戏(一)的更多相关文章
- 用C写一个简单的推箱子游戏(二)
下面接着上一篇随笔<用C写一个简单的推箱子游戏(一)>来写 tuidong()函数是用来判断游戏人物前方情况的函数,是推箱子游戏中非常重要的一个函数,下面从它开始继续介绍推箱子的小程序怎么 ...
- three.js 制作一个三维的推箱子游戏
今天郭先生发现大家更喜欢看我发的three.js小作品,今天我就发一个3d版本推箱子的游戏,其实webGL有很多框架,three.js并不合适做游戏引擎,但是可以尝试一些小游戏.在线案例请点击博客原文 ...
- 用while循环写一个简单的猜数字游戏
import random #练习:模拟猜数字的游戏 """ 计算机出一个1~100之间的随机数由人来猜 计算机根据人猜的数字分别给出 大一点/小一点/猜中了 的提示 & ...
- JavaScript写一个小乌龟推箱子游戏
推箱子游戏是老游戏了, 网上有各种各样的版本, 说下推箱子游戏的简单实现,以及我找到的一些参考视频和实例: 推箱子游戏的在线DEMO : 打开 如下是效果图: 这个拖箱子游戏做了移动端的适配, 我使用 ...
- 在Openfire上弄一个简单的推送系统
推送系统 说是推送系统有点大,其实就是一个消息广播功能吧.作用其实也就是由服务端接收到消息然后推送到订阅的客户端. 思路 对于推送最关键的是服务端向客户端发送数据,客户端向服务端订阅自己想要的消息.这 ...
- 用Python写一个简单的Web框架
一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...
- 如何写一个简单的http服务器
最近几天用C++写了一个简单的HTTP服务器,作为学习网络编程和Linux环境编程的练手项目,这篇文章记录我在写一个HTTP服务器过程中遇到的问题和学习到的知识. 服务器的源代码放在Github. H ...
- 如何写一个简单的shell
如何写一个简单的shell 看完<UNIX环境高级编程>后我就一直想写一个简单的shell来作为练习,因为有事断断续续的写了好几个月,如今写了差不多来总结一下. 源代码放在了Github: ...
- 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”
这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...
随机推荐
- 20190925-01安装redis 000 022
1.将redis压缩包放入Linux系统有4种办法. 第一:如果安装了VMware Tools工具可以直接进行拖拽 第二:在windows中找到配置好的共享文件夹将redis压缩包放入其中,在Linu ...
- Mybatis-使用注解开发
使用注解开发 [toc] 1. 面向接口编程 大家之前都学过面向对象编程,也学习过接口,但在真正的开发中,很多时候我们会选择面向接口编程 根本原因 : 解耦 , 可拓展 , 提高复用 , 分层开发中 ...
- parseQueryString
var parseQueryString = function (url) { var reg = /([^\?\=\&]+)\=([^\?\=\&]*)/g; var o ...
- 大揭秘| 我司项目组Gitlab Flow && DevOps流程
长话短说,本文全景呈现我司项目组gitlab flow && devops Git Flow定义了一个项目发布的分支模型,为管理具有预定发布周期的大型项目提供了一个健壮的框架. Dev ...
- 1. spring5源码 -- Spring整体脉络 IOC加载过程 Bean的生命周期
可以学习到什么? 0. spring整体脉络 1. 描述BeanFactory 2. BeanFactory和ApplicationContext的区别 3. 简述SpringIoC的加载过程 4. ...
- Windows下安装Nginx及负载均衡
1.下载Windows版本的Nginx http://nginx.org/en/download.html 2.解压Nginx包,配置conf文件下的nginx.conf文件 3.配置说明: #use ...
- 4.案例 - NIO实现TCP通信
服务端: package cn.tedu.nio.channel; import java.net.InetSocketAddress; import java.nio.ByteBuffer; imp ...
- vue中父子组件传值问题 通过props 和 $emit()方法
(代码在最后) 1.父组件给子组件传值直接通过props,听着很简单,但是对于初学者来说还是比较难以理解的,今天小白通过自己的实践操作结合代码分析一下 案例 把模态框单独的抽离出来,当作一个组件 第 ...
- 疑难杂症 | Excel VBA锁定指定单元格区域
背景:锁定EXCEL表头 一.手动操作流程 其基本逻辑并不赋值,手动操作流程是: 1.取消所有单元格的"锁定"格式 CTRL+A,选中全部的单元格→单击右键→设置单元格格式→保护→ ...
- 深夜,我偷听到程序员要对session下手……
我是一个web服务器 我是一个web服务器,我的工作是给人类提供上网服务,我每天要为数以万计的人提供网页浏览服务. 已经是深夜了,我还在和手下几个兄弟为了一件事紧张讨论着. "老大,现在咱们 ...