我现在在读大二,我们有一门课程叫《操作系统》,课程考查要求我们可以写一段程序或者写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写一个简单的推箱子游戏(二)》