推箱子游戏C语言解析.docx
《推箱子游戏C语言解析.docx》由会员分享,可在线阅读,更多相关《推箱子游戏C语言解析.docx(25页珍藏版)》请在冰豆网上搜索。
![推箱子游戏C语言解析.docx](https://file1.bdocx.com/fileroot1/2023-3/30/d8c97e83-90c6-4c2c-bb44-9fd397d64f7b/d8c97e83-90c6-4c2c-bb44-9fd397d64f7b1.gif)
推箱子游戏C语言解析
哈尔滨远东理工学院
C语言课程设计论文
题目:
推箱子游戏课程设计
姓名:
李瑞霖谢桂成?
分 院:
机器人科学与技术学院
专 业:
电子信息工程
学号:
1103031011030324110303?
指导教师:
李涛
二0一四年九月五日
推箱子游戏(C语言)
摘要
近年来随着科技的飞速发展,C语言的应用正在不断深入。
C语言目前是国际上比较流行的计算机高级编程语言之一,因其简洁、使用方便且具备强大的功能而受到编程人员的普通青睐。
它既适合作为系统描述语言,也可用来编写系统软件,还可以用来编写应用软件和设计游戏等。
本文着重分析用C语言实现一个简单的推箱子游戏,旨在介绍推箱子游戏的实现方法,并逐步介绍C语言图形编程的方法和技巧。
在C语言编写软件WIN-TC上,涉及软中断、二维数组、键盘操作及图形化函数等方面,显示器中断寄存器的设置、二维数组及结构体的定义、键盘上键值的获取、图形方式下光标的显示和定位,以及部分图形函数的使用实现了一个完整的推箱子游戏界面,界面清晰可见。
关键词:
C语言WIN-TC推箱子
Abstracts
Withtherapiddevelopmentofscienceandtechnology,inrecentyears,theClanguage,Clanguageisunceasinglythoroughalongwiththeapplication.Nowmorepopularinternationaladvancedcomputerprogramminglanguage,it'sasimple,easytouseandpowerfulsupportofordinaryprogrammers.Itsuitsasasystemdescriptionlanguage,canalsobeusedtowritethesystemsoftware,applicationsoftwarecanalsobeusedtowriteanddesignthegame.
ThispapermainlyanalysisusingClanguagetoachieveasimpleSokobangameaimedatintroducingtheSokobangameimplementationmethod,andgraduallyCgraphicsprogrammingmethodsandtechniquesareintroduced.InClanguagesoftware,WIN-TC,relatedsoftirqs,two-dimensionalarray,keyboard,andgraphicalfunctions,etc.,accordingtointerruptregisterSettings,two-dimensionalarray,andthestructuredefinedaccesskeyonthekeyboard,thegraphicsmode,thecursordisplaysandpositioning,andsomeofthegraphicsfunctionsisusedtoimplementacompleteSokobangameinterface,theinterfacecanbeclearlyseen.
Key:
ClanguageWIN-TCPushBox
前言1
1.课程设计概述2
1.1推箱子游戏软件功能概述2
1.2VisualC++6.0概述2
1.3设计的功能 2
1.4游戏的变成思想 3
1.4.1确定软件的功能 3
1.4.2定义软件的核心数据结构 3
1.4.3对整个软件进行功能模块的划分 3
1.4.4整个推箱子游戏功能介绍 4
2.程序总体设计5
2.1总体设计思想5
2.2功能模块设计 5
2.3总体设计流程图6
3.推箱子游戏软件详细设计8
3.1两个主要问题8
3.1.1地图的生成8
3.1.2人或人和箱子的移动8
3.2在源程序中声明与定义9
3.3数据结构设计 9
3.3.1设置全局变量 9
3.3.2定义结构体 9
3.4函数功能描述 10
3.4.1putoutChar() 函数10
3.4.2printWall() 函数10
3.4.3printBox()函数 10
3.4.4printBoxDes()函数 10
3.4.5printDestination()函数 10
3.4.6printDestination1()函数 11
3.4.7printMan()函数 11
3.4.8init()函数 11
3.4.9初始化游戏函数 11
3.4.10移动箱子函数 12
3.4.11judge()函数 12
3.4.12move()函数 12
3.4.13reset()函数 13
3.4.14主函数 13
4.程序测试14
5.总结15
6.程序源代码16
致 谢24
参考文献25
前言
随着计算机技术的发展,可视编程技术占有了越来越重要的作用。
Visual C++6.0 是一种功能强大行之有效的可视化编程工具。
因此此软件是在Visual C++6.0环境下编写的。
对于我们,随着学习的深入,已经大体掌握了Visual C++6.0环境下的程序开发。
为了将我们的编程能力提升到一个更高的水平,深化面向对象的编程思维和解决问题的能力,值此课程设计周期间,进行基于Visual C++6.0环境的软件开发,先以推箱子游戏作为开始,对Visual C++6.0环境和C语言的模块编程设计进行回忆和熟悉,有利于促进面向对象程序设计思想的理解,使得在此基础上的下一个软件的开发进行的更加顺利。
本文档详细叙述了基于Visual C++6.0环境下的推箱子游戏软件的设计过程以及程序源代码。
从概要设计,详细设计,参考源程序代码以及显示程序运行的截屏等方面详尽的介绍了软件开发过程。
此次推箱子游戏软件的开发目的是使我们用最基础的C语言程序设计的方式来思考和解决问题的能力,并且可以掌握二维数组的使用、循环控制的使用、地图的设计和使用以及C语言语法。
程序在设计的过程中遇到的问题已及时更正,但由于编者的能力和水平有限,推箱子游戏软件和文档中不免会出现一些不期待的错误,望文档读者能够理解和体谅,并欢迎提醒和纠正,在此表示感谢以及敬意。
1.课程设计概述
1.1推箱子游戏软件功能概述
在一个狭小的仓库中,把木箱放到指定的位置,通过控制人的走向来推箱子移动,箱子只能推动不能拉动,一次只能推动一个箱子。
稍不小心就会出现箱子无法移动或者通道被堵住的情况,所以需要巧妙的利用有限的空间和通道。
通过此游戏可以锻炼一个人的逻辑思维能力。
1.2VisualC++6.0概述
VisualC++是微软公司的重要产品之一,是一种功能强大行之有效的可视化编程工具。
它提供了MFC类库,使用户可以方便的开发自己想实现的功能。
VisualC++6.0的主要特点:
(1)自动化和宏功能。
(2)可以灵活地定制工具栏和菜单。
(3)可以直接运行和调试程序,还可以使用宏语言来自动操作调试器。
(4)支持Internet连接。
(5)一个新的便捷的项目系统可以允许一个工作区内包含多个不同的项目类型。
(6)在工作区内可以包含多个并列的工程文件。
(7)可以在对话框中使用WizardBar将程序同可视化元素联系起来。
(8)FindinFile命令支持两个独立的输出窗格,可以保存上一次搜索的结果。
这些新特性可以更好地利用VisualC++开发工具进行Windows应用程序开发。
1.3设计的功能
C语言是我们数计系都要学的一门基础学科。
那么,为什么不用C语言编一个游戏来玩呢?
学习程序设计,并不是一件艰苦、枯燥的事情,它能象电脑游戏一样充满好奇、富有乐趣,C语言对于电脑程序设计来说是一种非常重要的语言。
设计者只要完成对推箱子游戏的功能描述,就可以利用计算机和工具,进行设计处理,最终得到理想的设计结果。
本设计是基于C语言编程技术,用数据结构实现的,集科学性,先进性,创新性,实用性于一体,并在电脑屏幕上实现游戏界面的功能,包括选择游戏关卡和游戏挑战失败可按空格键重新开始。
1.4游戏的变成思想
1.4.1确定软件的功能
让玩家通过按上下左右键推箱子,当箱子们都推到了目的地后出现过关信息,并显示下一关。
推错了玩家还按空格键从新玩过这关。
直到过完全部关卡。
1.4.2定义软件的核心数据结构
我们定义一个二维数组ghouse来记录屏幕上各点的状态。
char ghouse[20][20]; 其中:
0表示什么都没有,'b'表示箱子,'w'表示墙壁,'m'表示目的地,'i'表示箱子在目的地。
1.4.3对整个软件进行功能模块的划分
(1)初始化:
在屏幕上输出欢迎信息,把ghouse数组的元素初始化为0。
并根据各关的要求在屏幕上输出墙、箱子、目的地和人。
并用ghouse 数组记录各点的状态。
(2)进入游戏循环:
这个游戏主循环是等待按键。
当接受到上下左右键时执行相关操作:
接受ESC键时退出游戏;接受空格键时返回本关开头;接受无效按键时做忽略处理。
重点介绍按上下左右键时如何执行相关操作。
(3)判断是否过关:
用一个链表win由每关的初始化函数传给main函数。
Win链表主要记录屏幕上的哪些点是目的地,并记录目的地的位置。
Main函数每执行一次操作后就判断屏幕上的目的地是不是都有箱子了。
1.4.4整个推箱子游戏功能介绍
本游戏一共4关,由易到难,每一关都有初化、按键处理、重置及退出功能。
(1)初始化包括屏幕初始化和每一关卡的初始化,屏幕被初始化宽80像素,高25像素。
(2)按键处理包括移动小人和移动箱子,通过移动上下左右键来控制小人的移动,从而推 动箱子,以把箱子推到指定的目的地为过关。
(3)每一关都可以重置,按空格键可以重置当前关。
(4)按Esc键可以在任何时候退出游戏。
2.程序总体设计
2.1总体设计思想
推箱子游戏软件的功能是锻炼人的逻辑思维能力。
推箱子游戏软件的功能模块有:
(1)提供菜单界面,方便用户对程序个功能进行选择,选择要实现的功能按相应的键进入该功能。
(2)地图的生成,用二维整型数组来构成地图,其中数字代表特殊的符号。
(3)移动,人或人和箱的移动,接受用户输入的一个字符,控制人的走向,并且可以在允许的情况下推动箱子。
(4)清屏功能,使用了清屏函数,当在游戏中时可以直接返回主菜单,
(5)利用了辅助色彩函数,使游戏界面更加好看,美观。
2.2功能模块设计
本程序包括5个模块,分别是初始化模块、画图模块、移动箱子模块、移动小人模块和功能控制模块,如图2.1所示。
各个模块的功能描述如下:
(1)初始化模块。
该模块包括屏幕初始化和游戏第一关的初始化。
屏幕初始化用于输出欢迎信息和操作提示,游戏每一关的初始化是构建每一关的关卡。
(2)画图模块。
该模块主要是被其它模块调用,用于画墙、在空地画箱子、在目的地画箱子、画小人和画目的地。
(3)移动箱子模块。
该模块用于移动箱子,包括目的地之间、空地之间和目的地与空地之间的箱子移动。
(4)移动小人模块。
该模块用于控制小人移动,从而推动箱子到目的地。
(5)功能控制模块。
该模块是几个功能函数的集合,包括屏幕输出功能、指定位置状态判断功能和关卡重置功能。
如图2.1所示:
图2.1游戏方块预览图
2.3总体设计流程图
游戏从第一关开始,按上下左右方向键控制小人移动来推动箱子,可以在游戏中的任何时候按Esc键退出。
如果游戏无成功希望,可以按空格键回到当前任务的开始状态;如果成功完成当前关,则进入下一关,如果当前关是最后一关,则显示通关信息,提示游戏结束。
小人移动的方向有4个,move()函数(处理小人移动的函数)对这4个方向移动的处理都一致,只是调用函数时的参数有所不同。
首先判断小人移动的方向,然后根据小人所处世的当前状态、下一步状态或者下下一步状态进行适当的处理。
总体设计流程如图2.2:
图2.2总体设计流程
3.推箱子游戏软件详细设计
3.1两个主要问题
设计中的两个主要需解决的问题是:
怎样生成地图、怎样实现人或人和箱子的移动。
3.1.1地图的生成
设计中用二维整型数组中的数字元素表示不同的物体,比如0代表空地,1代表墙,2代表非游戏的填充内容(非必须内容),可以使地图规则,3代表目的地,4代表箱子,6代表人。
然后用一个switch语句给每个数字赋予不同的符号,在输出二维数组,生成地图。
3.1.2人或人和箱子的移动
设计中要想使人移动,首先要找到人的起始位置,然后才能开始移动。
人向四个方向移动的原理是相同的,我们可以先研究一个方向的移动,找到人的位置后,以人向上走为例,因为向上走嘛(可以通过数组下标表示)。
(1)要判断人前面(上一行),是否为空地,是空地则可以移动,移动后判断并改变人员原位置的数值元素和空地原位置的数值元素;否则不移动。
(2)如果人前面是目的地,人也是可以移动的,同样判断人原位置数值元素,并改变人员位置的数值元素和前一位置的数值元素。
(3)如果人前是在空地上的箱子。
如果箱子前面又是空地,则可以移动,改变箱子前位置的数值元素,还是判断原位置的数值元素,然后改之;如果箱子前为目的地,和上面说的一样移动和改数值元素,只是多了计分这一步。
(4)如果人前是已经进入目的地的箱子。
如果箱子前又是空地,则可以移动箱子,但是要减分,改变空地位置的数值元素,判断人和箱子原地的数值元素,并改之;如果箱子前是另一目的地,方法同上,只是不减分。
用分数控制箱子是否已全在目的地。
(5)每一次的移动,必须要清屏,然后再显示一次地图,这样便可以实现人或人和箱子的移动
3.2在源程序中声明与定义
voiddraw_map(intmap[10][12])//地图函数,
voidmove(intmap[10][12])//移动函数
使用了:
#include//标准输入输出头文件
#include//system函数的头文件
#include//getch函数的头文件
多种头文件。
程序中还应用了:
printf(“\a”);//发出警报声
Static(intcount);//统计步数
程序分为多个小模块,通过调用实现各种功能,增强了程序的可建设性。
3.3数据结构设计
3.3.1设置全局变量
定义二维数组char status[20][20],用于记录屏幕一各点的状态。
其中,“0”表示什么都没有,“b”表示箱子,“w”表示目的地,“i”表示箱子在目的地。
首先将屏幕20*20范围内的状态初始化为0,然后根据具体情况,在画箱子时,将箱子所在点的状态改为“b”;在画墙壁时,将墙壁所在点的状态改为“w”;在画目的地时,将目的地所在点的状态改为“m”;当箱子被推到目的地时,箱子所在点的状态改为“i”,如果每一关中所有目的地的状态都为“i”,则说明该关已完成。
定义全局变量,char far *printScreen=(char far*)0xB8000000,用于在屏幕上输出字符。
彩色显示器的字符缓冲区首地址为0xB8000000,每一个字符占2个字节(第一个字节为ASCII值,第二个字节为颜色值),字符模式下屏幕宽80像素,高25像素,一屏可以写80*25个字符。
3.3.2定义结构体
typedef struct winer {
int x; int y;
struct winer *p; }winer;
定义结构体struct winer用于判断每一关是否已完成。
其中x用于存放目的地的横坐标,y用于存放目的地的纵坐标。
如果所有表示目的地坐标对应的状态都为“i”,即箱子在目的地,则表示已经过关,可以进入下一关。
该结构体的初始化在每一关的初始化时进行。
3.4函数功能描述
3.4.1putoutChar() 函数
函数原型:
void putoutChar(int y,int x,char ch,char fc,char bc)
putoutChar()函数在屏幕上的指定位置输出指定的字符。
其中,x、y指明输出的位置,ch表示输出的字符,fc表示输出的字符颜色,bc 表示背景色。
3.4.2printWall() 函数
函数原型:
void printWall(int x,int y)
printWall()函数用于画墙壁,传入参数x、y指明位置。
该函数调用putoutChar()进行输出,以黑色为背景画绿色墙,用小方块表示墙(ASCII值为219)。
3.4.3printBox()函数
函数原型:
void printBox(int x,int y)
printBox()函数用于在非目的地画箱子,传入参数x、y指明位置。
该函数调用putoutChar()进行输出,以黑色为背景白色箱子,用ASCII值为10的字符表示箱子。
3.4.4printBoxDes()函数
函数原型:
void printBoxDes(int x,int y)
printBoxDes()函数用于在目的地画箱子,传入参数x、y指明位置。
该函数调用putoutChar()进行输出,以黑色为背景画黄色箱子,仍用ASCII值为10的字符表示箱子。
3.4.5printDestination()函数
函数原型:
void printDestination(int x,int y)
printDestination()函数用于画目的地,传入参数x、y指明位置。
该函数调用putoutChar()进行输出,以黑色为背景画黄色目的地,用心型表示(ASCII值为003)。
3.4.6printDestination1()函数
函数原型:
void printDestination1(int x,int y,winer **win,winer **pw)
printDestination1()函数与printDestination()函数功能基本相同,都是画目的地函数,但是printDestination1()增加了记录每一个目的地位置的功能。
其中x、y指明目的地的位置,每一关的所有目的地位置存放在结构体struct winer中,形成一条链表,**winer返回链表的头,**pw则指向链表的尾部。
3.4.7printMan()函数
函数原型:
void printMan(int x,int y)
printMan()函数用于画小人。
X、y指明画的位置。
该函数通过软中断来实现,首先设置寄存器AX的高位和低位,设置高位0xa表示在光标位置显示字符;设置低位02(ASCII值),表示输出的字符;然后设置寄存器CX为01,表示重复输出的次数,这里只输出一次;最后产生类型为0x10的中断,表示显示器输出。
3.4.8init()函数
函数原型:
void init()
init()函数用于初始化屏幕。
该函数首先用两个for循环初始化屏幕20*20范围内的状态,初始化为0,以后根据实际情况重新赋值;然后设置屏幕输出状态,设置寄存器AX的高位为0,低位为3,表示以80*25的彩色方式显示;最后移动光标到指定的位置输出操作提示信息以及版权信息。
3.4.9初始化游戏函数
函数原型:
winer *initStep1()、winer *initStep2()、winer *initStep3()、winer *initStep4()。
这几个函数分别初始化游戏的第一关到第四关。
这些函数的功能和实现步骤相似。
首先根据需要在指定的位置画墙壁和画箱子,在这里可以设置游戏的难度,初始化的墙壁越复杂,箱子越多,则游戏就越难。
游戏的第一关至第四关难度依次增加。
然后分别调用printDestination1()和printMan()函数画目的地和小人。
函数返回包含各个目的地位置的链表。
3.4.10移动箱子函数
函数原型:
void moveBoxSpacetoSpace(int x,int y,char a)、void moveBoxDestoSpace(int x,int y, char a)、void moveBoxSpacetoDes(int x,int y,char a)、void moveBoxDestoDes(int x,int y,char a)
这几个函数实现的功能分别是人空地移动箱子到空地、从目的地移动箱子到空地、从空地移动箱子到目的地和中从目的地移动箱子到目的地。
X、y指明小人当前所处的位置,字符a表示移动的方向,有“u”、“d”、“l”和“r”4个值,分别表示向上、下、左、右移动。
这几个函数的实现原理大致相似。
对于前面两个函数,首先判断移动的方向,人小人所在的位置沿着移动的方向移动一步画小人,移动两步画箱子(调用printBox()函数),并设置状态为“b”;对于后面两个参数,首先判断移动的方向,从小人所在的位置沿着移动方向移动一步画小人,移动两上在目的地画箱子(调用printBoxDes()函数),并设置状态为“i”,表明箱子在目的地上。
3.4.11judge()函数
函数原型:
int judge(int x,int y)
judge()根据结构体struct[x][y]中存的值来判断该点的状态。
3.4.12move()函数
函数原型:
void moid(int x,int y,char a)
Move()函数根据按下的键来处理小人的移动。
小人移动的方向有上(“u”)、下(“d”)、左(“l”)、右(“r”)4个,4个方向的处理方式一样。
首先判断移动的方向,然后根据小人的当前位置、下一步位置以及下下一步位置所在的状态进行处理。
(1)若下一步所在位置的状态为墙壁(“w”),则直接退出,不作任何处理。
(2)若下一步所在位置的状态为目的地(“i”)或者什么都没有(“0”),
则:
① 若当前位置的状态为目的地,则在当前位置画目的地(调用
printDestination()函数)、在下一步位置画小人(调用printMan()函数)。
② 若当前位置的状态为非目的地,则输出空格清空当前位置的小人,并在
下一步位置画小人(调用printMan()函数)。
(3)若下一步所在位置的状态为箱子(“b”),则:
① 如果下下一步位置的状态为“0”,则把箱子从空地移动到空地(调用
moveBoxSpacetoSpace()函数),然