推箱子游戏c语言实训.docx

上传人:b****5 文档编号:29215644 上传时间:2023-07-21 格式:DOCX 页数:20 大小:20.78KB
下载 相关 举报
推箱子游戏c语言实训.docx_第1页
第1页 / 共20页
推箱子游戏c语言实训.docx_第2页
第2页 / 共20页
推箱子游戏c语言实训.docx_第3页
第3页 / 共20页
推箱子游戏c语言实训.docx_第4页
第4页 / 共20页
推箱子游戏c语言实训.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

推箱子游戏c语言实训.docx

《推箱子游戏c语言实训.docx》由会员分享,可在线阅读,更多相关《推箱子游戏c语言实训.docx(20页珍藏版)》请在冰豆网上搜索。

推箱子游戏c语言实训.docx

推箱子游戏c语言实训

实训四:

游戏篇

4.1推箱子游戏

【实训容】

(1)功能要求

经典的推箱子是一个来自日本的古老游戏,目的是在训练人的逻辑思考能力。

在一个狭小的仓库中,要求把木箱从开始位置推放到指定的位置。

在仓库有障碍物,稍不小心就会出现箱子无法移动或者通道被堵住的情况,而且箱子只能推,不能拉,所以需要巧妙的利用有限的空间和通道,合理安排移动的次序和位置,才能顺利的完成任务。

本游戏一共4关,由易到难,每一关都有初化、按键处理、重置及退出功能。

(1)初始化包括屏幕初始化和每一关卡的初始化,屏幕被初始化宽80像素,高25像素。

(2)按键处理包括移动小人和移动箱子,通过移动上下左右键来控制小人的移动,从而推动箱子,以把箱子推到指定的目的地为过关。

(3)每一关都可以重置,按空格键可以重置当前关。

(4)按Esc键可以在任何时候退出游戏。

(2)技术要求

定义二维数组charstatus[20][20],用于记录屏幕一各点的状态。

其中,“0”表示什么都没有,“b”表示箱子,“w”表示目的地,“i”表示箱子在目的地。

首先将屏幕20*20围的状态初始化为0,然后根据具体情况,在画箱子时,将箱子所在点的状态改为“b”;在画墙壁时,将墙壁所在点的状态改为“w”;在画目的地时,将目的地所在点的状态改为“m”;当箱子被推到目的地时,箱子所在点的状态改为“i”,如果每一关中所有目的地的状态都为“i”,则说明该关已完成。

定义字符指针charfar*printScreen=(charfar*)0xB8000000,用于在屏幕上输出字符。

彩色显示器的字符缓冲区首地址为0xB8000000,每一个字符占2个字节(第一个字节为ASCII值,第二个字节为颜色值),字符模式下屏幕宽80像素,高25像素,一屏可以写80*25个字符。

定义结构体typedefstructwiner{intx;inty;structwiner*p;}winer;

定义结构体structwiner用于判断每一关是否已完成。

其中x用于存放目的地的横坐标,y用于存放目的地的纵坐标。

如果所有表示目的地坐标对应的状态都为“i”,即箱子在目的地,则表示已经过关,可以进入下一关。

该结构体的初始化在每一关的初始化时进行。

【概要设计】本程序采用模块化设计,包括5个模块,分别是初始化模块、画图模块、移动箱子模块、移动小人模块和功能控制模块。

各个模块的功能描述如下:

(1)初始化模块。

该模块包括屏幕初始化和游戏第一关的初始化。

屏幕初始化用于输出欢迎信息和操作提示,游戏每一关的初始化是构建每一关的关卡。

(2)画图模块。

该模块主要是被其它模块调用,用于画墙、在空地画箱子、在目的地画箱子、画小人和画目的地。

(3)移动箱子模块。

该模块用于移动箱子,包括目的地之间、空地之间和目的地与空地之间的箱子移动。

(4)移动小人模块。

该模块用于控制小人移动,从而推动箱子到目的地。

(5)功能控制模块。

该模块是几个功能函数的集合,包括屏幕输出功能、指定位置状态判断功能和关卡重置功能。

游戏从第一关开始,按上下左右方向键控制小人移动来推动箱子,可以在游戏中的任何时候按Esc键退出。

如果游戏无成功希望,可以按空格键回到当前任务的开始状态;如果成功完成当前关,则进入下一关,如果当前关是最后一关,则显示通关信息,提示游戏结束。

【详细设计及实现】

(1)课题中的函数原型及功能说明。

1、putoutChar()

函数原型:

voidputoutChar(inty,intx,charch,charfc,charbc)

putoutChar()函数在屏幕上的指定位置输出指定的字符。

其中,x、y指明输出的位置,ch表示输出的字符,fc表示输出的字符颜色,bc表示背景色。

2、printWall()

函数原型:

voidprintWall(intx,inty)

printWall()函数用于画墙壁,传入参数x、y指明位置。

该函数调用putoutChar()进行输出,以黑色为背景画绿色墙,用小方块表示墙(ASCII值为219)。

3、printBox()

函数原型:

voidprintBox(intx,inty)

printBox()函数用于在非目的地画箱子,传入参数x、y指明位置。

该函数调用putoutChar()进行输出,以黑色为背景白色箱子,用ASCII值为10的字符表示箱子。

4、printBoxDes()

函数原型:

voidprintBoxDes(intx,inty)

printBoxDes()函数用于在目的地画箱子,传入参数x、y指明位置。

该函数调用putoutChar()进行输出,以黑色为背景画黄色箱子,仍用ASCII值为10的字符表示箱子。

5、printDestination()

函数原型:

voidprintDestination(intx,inty)

printDestination()函数用于画目的地,传入参数x、y指明位置。

该函数调用putoutChar()进行输出,以黑色为背景画黄色目的地,用心型表示(ASCII值为003)。

6、printDestination1()

函数原型:

voidprintDestination1(intx,inty,winer**win,winer**pw)

printDestination1()函数与printDestination()函数功能基本相同,都是画目的地函数,但是printDestination1()增加了记录每一个目的地位置的功能。

其中x、y指明目的地的位置,每一关的所有目的地位置存放在结构体structwiner中,形成一条链表,**winer返回链表的头,**pw则指向链表的尾部。

7、printMan()

函数原型:

voidprintMan(intx,inty)

printMan()函数用于画小人。

X、y指明画的位置。

该函数通过软中断来实现,首先设置寄存器AX的高位和低位,设置高位0xa表示在光标位置显示字符;设置低位02(ASCII值),表示输出的字符;然后设置寄存器CX为01,表示重复输出的次数,这里只输出一次;最后产生类型为0x10的中断,表示显示器输出。

8、init()

函数原型:

voidinit()

init()函数用于初始化屏幕。

该函数首先用两个for循环初始化屏幕20*20围的状态,初始化为0,以后根据实际情况重新赋值;然后设置屏幕输出状态,设置寄存器AX的高位为0,低位为3,表示以80*25的彩色方式显示;最后移动光标到指定的位置输出操作提示信息以及信息。

9、初始化游戏

函数原型:

winer*initStep1()、winer*initStep2()、winer*initStep3()、winer*initStep4()

这几个函数分别初始化游戏的第一关到第四关。

这些函数的功能和实现步骤相似。

首先根据需要在指定的位置画墙壁和画箱子,在这里可以设置游戏的难度,初始化的墙壁越复杂,箱子越多,则游戏就越难。

游戏的第一关至第四关难度依次增加。

然后分别调用printDestination1()和printMan()函数画目的地和小人。

函数返回包含各个目的地位置的链表。

10、移动箱子

函数原型:

voidmoveBoxSpacetoSpace(intx,inty,chara)、voidmoveBoxDestoSpace(intx,inty,chara)、voidmoveBoxSpacetoDes(intx,inty,chara)、voidmoveBoxDestoDes(intx,inty,chara)

这几个函数实现的功能分别是人空地移动箱子到空地、从目的地移动箱子到空地、从空地移动箱子到目的地和中从目的地移动箱子到目的地。

X、y指明小人当前所处的位置,字符a表示移动的方向,有“u”、“d”、“l”和“r”4个值,分别表示向上、下、左、右移动。

这几个函数的实现原理大致相似。

对于前面两个函数,首先判断移动的方向,人小人所在的位置沿着移动的方向移动一步画小人,移动两步画箱子(调用printBox()函数),并设置状态为“b”;对于后面两个参数,首先判断移动的方向,从小人所在的位置沿着移动方向移动一步画小人,移动两上在目的地画箱子(调用printBoxDes()函数),并设置状态为“i”,表明箱子在目的地上。

11、judge()

函数原型:

intjudge(intx,inty)

judge()根据结构体struct[x][y]中存的值来判断该点的状态。

12、move()

函数原型:

voidmoid(intx,inty,chara)。

Move()函数根据按下的键来处理小人的移动。

小人移动的方向有上(“u”)、下(“d”)、左(“l”)、右(“r”)4个,4个方向的处理方式一样。

首先判断移动的方向,然后根据小人的当前位置、下一步位置以及下下一步位置所在的状态进行处理。

若下一步所在位置的状态为墙壁(“w”),则直接退出,不作任何处理。

若下一步所在位置的状态为目的地(“i”)或者什么都没有(“0”),则:

若当前位置的状态为目的地,则在当前位置画目的地(调用printDestination()函数)、在下一步位置画小人(调用printMan()函数)。

若当前位置的状态为非目的地,则输出空格清空当前位置的小人,并在下一步位置画小人(调用printMan()函数)。

若下一步所在位置的状态为箱子(“b”),则:

①如果下下一步位置的状态为“0”,则把箱子从空地移动到空地(调用moveBoxSpacetoSpace()函数),然后把光标移动到下一步位置(如果当前位置的状态为目的地,则应先画目的地(调用printDestinanion()函数))。

②如果下下一步位置的状态为目的地,则把箱子从空地移动到目的地(调用moveBoxSpacetoDes()函数),然后把光标移动到下一步位置(如果当前位置的状态为目的地,则应先画目的地(调用printDestination()函数))。

③其它情况则直接返回,不作任何处理。

若下一步所在位置的状态为箱子在目的地(“i”),则:

如果下下一步位置的状态为“0”,则把箱子从目的地移动到空地(调用moveBoxDestoSpace()函数),然后把光标移动到下一步位置(如果当前位置的状态为目的地,则应先画目的地(调用printDestination()函数))。

如果下下一步位置的状态为目的地,则把箱子从目的地移动到目的地(调用moveBoxDestoDes()函数),然后把光标移动到下一步位置(如果当前位置的状态为目的地,则应先画目的地(调用printDestination()函数))。

其它情况则直接返回,不作任何处理。

13、reset()

函数原型:

voidreset(inti)

reset()函数的功能是重置当前关。

该函数首先判断当前关是第几关,然后调用init()函数和初始化当前关的函数进行重置。

14、主函数

主函数首先设置寄存器AX的高位和低位,显示器软中断,进行显示状态的设置,初始化屏幕,初始化第一关,并显示操作提示信息和信息。

然后根据按下的键(bioskey(0)函数返回按下的键值)进行处理,处理过程由move()函数进行(如果按下Esc键,则退出程序)。

对于每一关,如果所有的表示目的地的状态都由“m”变成了“i”,则表示通过该关,可以进入下一关。

(2)主要代码实现及运行效果图(代码在turboc2.0下通过,游戏界面截图如下)。

1、程序预处理

程序预处理部分包括加载头文件、定义全局变量和定义数据结构,并对它们进行初始化工作。

其中加载头文件的代码如下:

#include

#include

#include

#include

#include

#include

2、初始化模块

该模块主要用于对屏幕和关卡的初始化,初始化关卡时是调用画图模块中画图函数。

该模块包括以下几个函数。

(1)voidinit(),初始化屏幕的大小、显示方式、显示操作提示信息和信息。

(2)winer*initStep1(),初始化游戏的第一关。

(3)winer*initStep2(),初始化游戏的第二关。

(4)winer*initStep3(),初始化游戏的第三关。

(5)winer*initStep4(),初始化游戏的第四关。

其中初始化屏幕函数的详细代码如下:

voidinit()

{

inti,j;

for(i=0;i<20;i++)

for(j=0;j<20;j++)

/*屏幕20*20围状态初始化为0,表示什么都没有*/

status[i][j]=0;

/*设置寄存器AX低位,80*25彩色方式显示*/

_AL=3;

/*设置寄存器AX高位*/

_AH=0;

geninterrupt(0x10);

/*移动光标到指定位置输出屏幕信息*/

gotoxy(41,4);

printf("---------up");

gotoxy(41,6);

printf("---------down");

gotoxy(41,8);

printf("---------left");

gotoxy(41,10);

printf("---------right");

gotoxy(40,12);

printf("Space-----reset");

gotoxy(40,14);

printf("Esc-------quit");

gotoxy(18,24);

printf("CopyRight:

2008LuoFuxing");

gotoxy(40,4);

_CX=01;

_AH=0xa;

_AL=24;

geninterrupt(0x10);

gotoxy(40,6);

_CX=01;

_AH=0xa;

_AL=25;

geninterrupt(0x10);

gotoxy(40,8);

_CX=01;

_AH=0xa;

_AL=27;

geninterrupt(0x10);

gotoxy(40,10);

_CX=01;

_AH=0xa;

_AL=26;

geninterrupt(0x10);

}

3、画图模块

该模块主要用于画图操作,包括画墙、画箱子、画目的地和画小人等。

该模块包括以下几个函数。

(1)voidprintWall(intx,inty),用于画墙。

(2)voidprintBox(intx,inty),在空白地(非目的地)画箱子。

(3)voidprintBoxDes(intx,inty),在目的地画箱子。

(4)voidprintDestination(intx,inty),画目的地函数。

(5)voidprintDestination1(intx,inty,winer**win,winer**pw),画目的地函数,并记录每个目的地的位置。

(6)voidprintMan(intx,inty),画小人函数。

其中画墙函数的代码如下:

voidprintWall(intx,inty)

{

/*以黑色为背景画绿色墙,用小方块表示*/

putoutChar(y-1,x-1,219,GREEN,BLACK);

/*记录状态为墙*/

status[x][y]='w';

}

4、移动箱子模块

该模块是实现箱子的移动。

根据游戏规则,箱子可以在空地之间、目的地之间、空地和目的地之间来回移动,因此,实现本模块共有以下4个函数。

(1)voidmoveBoxSpacetoSpace(intx,inty,chara),把箱子从空地移动到空地。

(2)voidmoveBoxDestoSpace(intx,inty,chara),把箱子从目的地移动到空地。

(3)voidmoveBoxSpacetoDes(intx,inty,chara),把箱子从空地移动到目的地。

(4)voidmoveBoxDestoDes(intx,inty,chara),把箱子从目的地移动到目的地。

其中从空地移动箱子到空地函数的详细代码如下:

voidmoveBoxSpacetoSpace(intx,inty,chara)

{

switch(a)

{

/*如果按向上键*/

case'u':

/*重设((x-1),y)位置的状态为0*/

status[x-1][y]=0;

/*清空(x,y)处原有的小人*/

printf("");

/*在((x-2),y)处重新画箱子*/

printBox(x-2,y);

/*在((x-1),y)处重新画小人*/

printMan(x-1,y);

/*重设((x-2),y)位置的状态为箱子*/

status[x-2][y]='b';

break;

/*如果按向下键*/

case'd':

status[x+1][y]=0;

printf("");

printBox(x+2,y);

printMan(x+1,y);

status[x+2][y]='b';

break;

/*如果按向左键*/

case'l':

status[x][y-1]=0;

printf("");

printBox(x,y-2);

printMan(x,y-1);

status[x][y-2]='b';

break;

/*如果按向右键*/

case'r':

status[x][y+1]=0;

printf("");

printBox(x,y+2);

printMan(x,y+1);

status[x][y+2]='b';

break;

default:

break;

}

}

5、移动小人模块

移动小人模块是本程序的核心模块,仅由move()函数来实现。

Move()函数控制小人的移动,并调用画图模块、移动箱子模块中的函数来实现箱子的重画、移动等操作。

其操作流程可参见图(三)。

部分代码如下:

voidmove(intx,inty,chara)

{

switch(a)

{

/*如果按向上键*/

case'u':

/*如果(x-1,y)即小人的下一步状态为墙*/

if(!

judge(x-1,y))

{

/*则跳转到(y,x),并跳出循环*/

gotoxy(y,x);

break;

}

/*如果小人的下一步状态为目的地或者什么都没有*/

elseif(judge(x-1,y)==1||judge(x-1,y)==3)

{

/*如果当前状态为目的地*/

if(judge(x,y)==3)

{

/*画目的地*/

printDestination(x,y);

/*在新位置重新画小人*/

printMan(x-1,y);

break;

}

/*如果下一步状态为0*/

else

{

/*输出空字符,覆盖当前状态的小人*/

printf("");

/*在下一步重新画小人*/

printMan(x-1,y);

break;

}

}

/*如果下一步状态是箱子*/

elseif(judge(x-1,y)==2)

{

/*如果下下一步为空*/

if(judge(x-2,y)==1)

{

/*则将箱子从空地向上移动到空地*/

moveBoxSpacetoSpace(x,y,'u');

/*如果当前状态为目的地*/

if(judge(x,y)==3)

/*画目的地*/

printDestination(x,y);

gotoxy(y,x-1);

}

/*如果下下一步为目的地*/

elseif(judge(x-2,y)==3)

{

/*则将箱子从空地向上移动到目的地*/

moveBoxSpacetoDes(x,y,'u');

if(judge(x,y)==3)

printDestination(x,y);

gotoxy(y,x-1);

}

else

gotoxy(y,x);

break;

}

……

……

6、功能控制模块

功能控制模块包括屏幕输出功能、关卡重置功能和坐标位置状态的判断功能。

该模块包括以下几个函数。

(1)voidputoutChar(inty,intx,charfc,charbc),在屏幕上指定的位置输出指定的字符。

(2)intjudge(intx,inty),判断位置(x,y)处的状态,状态值可参见“数据结构设计”部分。

(3)voidreset(inti),重置关卡。

其中在屏幕上的指定位置输出指定的字符函数的代码如下:

voidputoutChar(inty,intx,charch,charfc,charbc)

{

/*屏幕输出字符*/

printScreen[(x*160)+(y<<1)+0]=ch;

/*指定字符颜色fc,背景色bc*/

printScreen[(x*160)+(y<<1)+1]=(bc*16)+fc;

}

 

7、主函数

主函数实现整个程序的控制,其游戏操作流程可参见图

(二)。

详细代码如下:

voidmain()

{

/*记录按下的键*/

intkey;

intx;

inty;

/*记录未被推到目的地的箱子个数*/

ints;

/*记录已经过了几关*/

inti=0;

winer*win;

winer*pw;

/*设置寄存器AX低位*/

_AL=3;

/*设置寄存器AX高位*/

_AH=0;

geninterrupt(0x10);

init();

win=initStep1();

do{

/*设置AH,读取光标位置*/

_AH=3;

geninterrupt(0x10);

/*读取光标所在的行,加1*/

x=_DH+1;

/*读取光标所在的列,加1*/

y=_DL+1;

/*bioskey

(1)返回0,直到有键按下*/

while(bioskey

(1)==0);

/*返回按下的键*/

key=bioskey(0);

switch(key)

{

/*如果按下向上键*/

case0x4800:

move(x,y,'u');

break;

/*如果按下向下键*/

case0x5000:

move(x,y,'d');

break;

/*如果按下向左键*/

case0x4b00:

move(x,y,'l');

break;

/*如果按下向右键*/

case0x4d00:

move(x,y,'r');

break

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 书信模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1