用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写一个简单的网页版“我的世界小游戏”
这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...
随机推荐
- 创建DBA用户luna
用system/pswd登陆sql plus,执行下面命令: 请输入用户名: system 输入口令: 连接到: Oracle Database 11g Enterprise Edition Rele ...
- 为什么ping不通google.com
前言 为什么在ping不通Google的时候,我们却可以web直接访问Google (已开启SSR 翻 墙) SSR访问Google 因为GFW的限制导致国内无法直接访问谷歌,那么SSR为什么能绕过限 ...
- vue3剖析:响应式原理——effect
响应式原理 源码目录:https://github.com/vuejs/vue-next/tree/master/packages/reactivity 模块 ref: reactive: compu ...
- poi自动生成Ecxel表格和Chart图表
最近因为业务需求,需要做poi自动导出Ecxel表格和Chart折线图的功能. 所以我在网上找到了一篇关于poi生成Chart图表的博客,代码很详细,但是缺少相关注释说明. 想要将它改造成自己需要的样 ...
- 虚拟PWN初探
前言 之前看到星盟Q群里面的消息,Freedom师傅在B站直播关于虚拟pwn入门的公开课,然后就去听了一波,感觉受益匪浅.之前一直以为虚拟pwn是超级复杂的东西,今年打比赛也遇到了好几次,一直无从下手 ...
- C#开发PACS医学影像处理系统(二):界面布局之菜单栏
在菜单栏布局上,为了使用自定义窗体样式和按钮,我们需要先将窗体设置为无边框,然后添加一个Grid作为菜单栏并置顶,VerticalAlignment="Top" logo图片和标题 ...
- 编程体系结构(03):Java集合容器
本文源码:GitHub·点这里 || GitEE·点这里 一.集合容器简介 集合容器是Java开发中最基础API模块,通常用来存储运行时动态创建的元素,基本特点如下: 泛型特点,存储任意类型对象: 动 ...
- 调整JavaScript抽象的迭代方案
原文链接:Adapting JavaScript Abstractions Over Time 译者:小溪里 校对者:郭华翔.苗冬青 即使还没有读过我的文章<在处理网络数据的 JavaScrip ...
- oracle分区怎么使用
1.什么是分区 分区的实质是把一张大表的数据按照某种规则使用多张子表来存储.然后这多张子表使用统一的表名对外提供服务,子表实际对用户不可见.类似于在多张子表上建立一个视图,然后用户直接使用该视图来访问 ...
- Oracle命令类别
Oracle命令类别: 数据操纵语言:DML: select; insert; delete; update; merge. 数据定义语言:DDL: create; alter; drop; trun ...