推箱子C课程设计报告

发布时间:2024-11-28

程序设计课程设计报告书

学生 : 孟祥煜

指导老师: 曾宇容

课程设计名称: 推箱子小游戏

班级: 软件11401

一、 设计任务

介绍推箱子游戏的实现方法,并逐步介绍C语言图形编程的方法和技巧。在C语言编写软件WIN-TC上,涉及软中断、二维数组、键盘操作及图形化函数等方法,显示器中断寄存器的设置、二维数组的定义、键盘上键值的获取、图形方式下光标的显示和定位,以及部分图形函数的使用实现了一个完整的推箱子游戏界面,界面清晰可见。 二、 设计目的

训练学生掌握C的数据结构和综合编程能力和游戏开发技巧等应用能力。

初步设想

推箱子是一款经典的益智小游戏,目的是在训练人的逻辑思考能力。在一个狭小的空间中,要求把木箱从起始位置处推放到指定位置。在空间中有地方限制,稍不小心就会出现箱子无法移动或者通道被堵住的情况,而且箱子只能推不能拉,所以需要玩家巧妙的利用有限的空间和通道,合理的移动次序和位置,才能完成任务。本游戏一共分14关,由易到难,每一关都随着关数的增加来增加难度,从而达到吸引游戏玩家的目的。

三 功能

1、菜单功能,玩家通过看目录按对应的键可以进入对应的功能菜单,其中1进入游戏,2选择游戏关卡,3游戏帮助指南 ,4退出游戏。 2 游戏功能: 玩家可以通过操纵键盘中的上下左右键进入游戏进行各种操作来完成游戏。

3 循环功能:当玩家正在游戏的时候如果某一步走错了,导致游戏无法完成,可以随时重新开始游戏来完成关卡,游戏过程中可以随时按Ctrl+V退出游戏。

4 顺序功能: 当玩家完成了某一关之后,随着进入下一关门可以按顺序进入下一关,继续开始更有挑战的关卡,如果该关是最后一关,则显示通关完成。 三、 总体设计 1、 功能模块设计

函数功能描述本程序包括5个模块,分别是初始化模块、画图模块、移动箱子模块、移动小人模块和功能控制模块。各个模块功能的功能描述如下: (1)初始化模块。该模块包括屏幕初始化和游戏第一关到第最后一关的初

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

(2)画图模块。该模块主要是被其他模块调用,用于画墙、在空地画箱子、

在目的地画箱子、画小人和画目的地。

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

目的地与空地之间箱子的移动。

(4)移动小人模块。该模块是几个功能函数的集合,包括屏幕输出功能、

指定位置状态判断功能和关卡重置功能。

(5)功能控制模块。该模块是几个功能函数的集合,包括屏幕输出功能、

指定位置状态判断功能和关卡重置功能。

任务执行流程图 数据流程图

游戏从第一关开始,按上下左右方向键控制小人移动来推动箱子,可以在游戏中的任何时候按Esc键退出。如果游戏无成功希望,可以按CTRI+V回到当前任务的开始状态;如果成功完成当前关,则进入下一关,

如果当前关是最后一关,则显示通关信息,提示游戏结束。 小人移动流程图

小人移动的方向有4个,move()函数(处理小人移动的函数)对这4个方向移动的处理都一致,只是调用函数时的参数有所不同。首先判断小人移动的方向,然后根 据小人所处世的当前状态、下一步状态或者下下一步状态进行适当的处理。

2、 数据结构设计 设置全局变量

定义int v[13][17],用于记录箱子在屏幕中哪个坐标上。其中“0”表示什么都没有。定义了int num_guan指现在的关数,int num_xiang;箱子的个数,int move_num人行走的次数;int push_num人推箱子的次数;定义数组int M[2]表示人所在的位置; M[0] 是人所在位置的横坐标 M[1]是人所在位置的纵坐标;定义数组int door[2]表示门所在的坐标,door[0]是“下一关门”的横坐标,door[1]是“下一关门”的纵坐标。

3主函数

下面让我们来看看主函数的操作流程,主函数首先进入游戏目录,提醒游戏玩家输入对应的数字来进行的对应的操作,如果玩家输入1则进入游戏第一关,输入2选择关卡进入,输入3显示游戏帮助菜单,帮助玩家更好的理解这个游戏的规则,输入4退出游戏。进入游戏后,首先调用chushi1()函数初始化要使用的页面,之后程序进入play()函数,play()函数中通过if语句通过判断i的值来初始化不同的关卡(设置好关卡的人,箱子,箱子的目的地,门),接着程序进入control函数通过获取玩家在键盘上的操作来分别对游戏人物进行操作,最后通过wancheng函数来对操作进行判断,如果判断成功的话则进入下一关游戏。反之则失败。一直通过到最后一个则通关成功。

四 代码设计(或编程)

①单个模块或函数处理

将整个系统程序分解为各个单独的模块,即C的函数,各模块可单独编译; ②整个程序的联调

在各个模块基本的单独编译通过后,用主函数将他们集成在一起,实现调用,并进行输出数据的可靠性、输入数据及系统的容错性测试。 五 程序说明书 功能模块 1. play() 2. control() 3. Daying() 4. Wancheng() 解析

1. play()

play()函数在这个程序中的功能主要是按1进入游戏系统后自动按照顺序进行游戏和完成每一关游戏后进入下一关关卡,其中变量i控制关卡的关数,j

控制进入下一关,首先利用if语句将i从一开始,初始化完成第一关,通过play()函数中的内嵌函数control()函数来控制游戏中人和箱子的各种操作,当过关了control()函数return 0.即j=control()中的j等于0,游戏进入下一关。依次类推,当完成14关之后j=1游戏结束。 void play() {

int i,j=0;

for(i=1;i<=20;i++) { tem=0;system("cls");//清屏

if(i==1) chushihua_guan1(); //设置关卡1的墙,箱子,人。 门 else if(i==2) chushihua_guan2(); else if(i==3) chushihua_guan3(); else if(i==4) chushihua_guan4(); else if(i==5) chushihua_guan5(); else if(i==6) chushihua_guan6(); else if(i==7) chushihua_guan7(); else if(i==8) chushihua_guan8(); else if(i==9) chushihua_guan9(); else if(i==10) chushihua_guan10(); else if(i==11) chushihua_guan11(); else if(i==12) chushihua_guan12(); else if(i==13) chushihua_guan13(); else if(i==14) chushihua_guan14(); j=control();if(j==1){system("cls");return ;} } }

2 control()

Control()在这个程序中主要控制游戏中人物和箱子的运动,当玩家在键盘进行各种操作时系统会给出不同的反应。模块中定义了command变量,来接收玩家在键盘上的各种操作,首先调用getch()函数为command赋一个初值command=(“空字符”)22, 进入界面图表初始化,根据num_guan的大小来具体初始化对应的关卡(箱子,人,墙的图标),接着模块进入了“控制阶段”,再次通过getch()函数command获得一个字符,当command=”H”(也就是↑)时人进行向上前进的动作,对应的(“P” ”K” ”M”)进行人的↓、←、→操作,以及人的上下左右推箱子的动作,同时当人的前进的方向是墙或者双层箱子的时候人则不能运动,人推箱子如果箱子的前面是墙或者箱子的话箱子和人都不能运动。运动过程中如果玩家输入

ctrl+c时游戏此关卡重新开始,同时在control函数中调用一个win变量来判断是否完成了游戏,调用内嵌函数wancheng() 函数,当((win=wancheng())==1&&v[door[0]][door[1]]==ren)时,表示这个关

卡已经完成了,return 0,即把play()函数中的j赋值等于0,游戏进入下一个关。 游戏过程玩家每操作一步,系统通过控制daying()函数来控制画面中目标的运动,来达到游戏的目的。 int control() {

int win; int temm; char

//存放接收到命令 while(1) {

command=getch(); //输入一个字符

command;

/* if(command==1)

if(command==22) {

if(num_guan==1)

{system("cls");chushihua_guan1();}

else if(num_guan==2) {system("cls");chushihua_guan2();} else if(num_guan==3) {system("cls");chushihua_guan3();} else if(num_guan==4) {system("cls");chushihua_guan4();} else if(num_guan==5) {system("cls");chushihua_guan5();} else if(num_guan==6) {system("cls");chushihua_guan6();}

else if(num_guan==8) {system("cls");chushihua_guan8();} else if(num_guan==9) {system("cls");chushihua_guan9();} else

if(num_guan==10)

{system("cls");chushihua_guan10();}

else

if(num_guan==11)

{system("cls");chushihua_guan11();}

else

if(num_guan==12)

{system("cls");chushihua_guan12();}

else

if(num_guan==1113)

{system("cls");chushihua_guan13();}

else

if(num_guan==14)

{system("cls");chushihua_guan14();}

}

if(command==-32) //F11,F12:-123,-122

{

temm=0;command=getch(); if(temm==0&&command=='H'

&& &&

(v[M[0]-1][M[1]]==xiang||v[M[0]-1][M[1]]==oxiang)

v[M[0]-2][M[1]]==jia) //箱子在人的上边或者 人的上边的箱子已经放好了且人的上面两行就是箱子的家

{ v[M[0]-1][M[1]]=ren; //H指的是向上推箱子到家

v[M[0]-2][M[1]]=oxiang;

M[0]=M[0]-1;move_num=move_num+1;push_num=push_num+1;

temm=temm+1;}

&& &&

if(temm==0&&command=='P'

(v[M[0]+1][M[1]]==xiang||v[M[0]+1][M[1]]==oxiang) v[M[0]+2][M[1]]==jia)

{ v[M[0]+1][M[1]]=ren;temm=temm+1; //P指向下

推箱子到家

v[M[0]][M[1]]=0; v[M[0]+2][M[1]]=oxiang;

M[0]=M[0]+1;move_num=move_num+1;push_num=push_num+1;}

if(temm==0&&command=='K'

&& &&

(v[M[0]][M[1]-1]==xiang||v[M[0]][M[1]-1]==oxiang) v[M[0]][M[1]-2]==jia)

{ v[M[0]][M[1]-1]=ren; //K指向左推箱子到家

v[M[0]][M[1]]=0;temm=temm+1; v[M[0]][M[1]-2]=oxiang;

1;}

if(temm==0&&command=='M'

&& &&

(v[M[0]][M[1]+1]==xiang||v[M[0]][M[1]+1]==oxiang) v[M[0]][M[1]+2]==jia)

{ v[M[0]][M[1]+1]=ren;temm=temm+1; //M指向右推

箱子到家

v[M[0]][M[1]]=0; v[M[0]][M[1]+2]=oxiang;

M[1]=M[1]+1;move_num=move_num+1;push_num=push_num+1;}//H指人把箱子向上推,不是推到家

if(temm==0&&command=='H'

&& &&

(v[M[0]-1][M[1]]==xiang||v[M[0]-1][M[1]]==oxiang) (v[M[0]-2][M[1]]==0||v[M[0]-2][M[1]]==jia))

{

v[M[0]-1][M[1]]=ren;temm=temm+1;v[M[0]][M[1]]=0;v[M[0]-2][M[1]]=xiang;M[0]=M[0]-1;move_num=move_num+1;push_num=push_num+1;}

if(temm==0&&command=='H'

&&

(v[M[0]-1][M[1]]==0||v[M[0]-1][M[1]]==jia||v[M[0]-1][M[1]]==men))

{

=move_num+1;M[0]=M[0]-1;}

//人向上走

&&

if(temm==0&&command=='P'

(v[M[0]+1][M[1]]==0||v[M[0]+1][M[1]]==jia||v[M[0]+1][M[1]]==men))

{ v[M[0]+1][M[1]]=ren;temm=temm+1; //人的下面为

空或者下面为家或者下面为门的时候 向下走

v[M[0]][M[1]]=0;

M[0]=M[0]+1;move_num=move_num+1;} if(temm==0&&command=='P'

&& &&

(v[M[0]+1][M[1]]==xiang||v[M[0]+1][M[1]]==oxiang) (v[M[0]+2][M[1]]==0||v[M[0]+2][M[1]]==jia))

{ v[M[0]+1][M[1]]=ren; //人的下面为箱子或者下

面已经有箱子找到家了 切 下面的下面是空或者下面的下面是家,人把箱子向下推,人往下面走

v[M[0]][M[1]]=0;temm=temm+1; v[M[0]+2][M[1]]=xiang;

M[0]=M[0]+1;move_num=move_num+1;push_num=push_num+1;}

if(temm==0&&command=='K'

&&

(v[M[0]][M[1]-1]==0||v[M[0]][M[1]-1]==jia||v[M[0]][M[1]-1]==men))

{ v[M[0]][M[1]-1]=ren;temm=temm+1; //人的左边为

空或者左边是家或者左边是门的时候人可以往左边走

v[M[0]][M[1]]=0;

M[1]=M[1]-1;move_num=move_num+1;}

&& &&

if(temm==0&&command=='K'

(v[M[0]][M[1]-1]==xiang||v[M[0]][M[1]-1]==oxiang) (v[M[0]][M[1]-2]==0||v[M[0]][M[1]-2]==jia))

{

v[M[0]][M[1]-1]=ren;temm=temm+1;//人的左边是箱子

或者人的左边是已经找到家的箱子切 人的左边的左边是空或者人的左边的左边是家的时候箱子可以往左边移动,

v[M[0]][M[1]]=0; v[M[0]][M[1]-2]=xiang;

M[1]=M[1]-1;move_num=move_num+1;push_num=push_num+1;}

if(temm==0&&command=='M'

&&

(v[M[0]][M[1]+1]==0||v[M[0]][M[1]+1]==jia||v[M[0]][M[1]+1]==men))

{

v[M[0]][M[1]+1]=ren;temm=temm+1;v[M[0]][M[1]]=0;M[1]=M[1]+1;move_num=move_num+1;} //人的右边是空的或者人的右边是家或者人的右边的门的时候人可以往右边走。

if(temm==0&&command=='M'

&& &&

(v[M[0]][M[1]+1]==xiang||v[M[0]][M[1]+1]==oxiang)

(v[M[0]][M[1]+2]==0||v[M[0]][M[1]+2]==jia))

{ v[M[0]][M[1]+1]=ren;temm=temm+1;v[M[0]][M[1]]=0;v[M[0]][M[1]+2]=xiang; //人的右边是箱子或者人的右边是一个已经找到家的箱子切右边的右边是空的或者右边的右边是家的时候可以推箱子

M[1]=M[1]+1;move_num=move_num+1;push_num=push_num+1;}

// else if(command==-122 || command==-123) ; // else ; }

// else if(command==0)

//command=getch();

//接收Fn的下一个字符 //F1~F10:59~68

else

1;}

if(command>=2&&command<=26){if(command==3)return else ; //Ctrl+a~z:1~26 当为ctrl+c的时候程序结束

if(win=wancheng()==0) tem=0; system("cls");dayin();

if((win=wancheng())==1&&v[door[0]][door[1]]==ren)

{Sleep(225);return 0;}}

return 0; //如果门的坐标和人的坐标相等的时候直接退出此语句,进入下一个程序(俗称下一关 )

} 3 Daying()

Daying函数在这个程序主要在游戏中的功能是画出游戏中人和箱子和“完成门”家,人的图标和对游戏中的关卡和人走的步数和推箱子的步数进行计数数,根据游戏中玩家的操作随时的对游戏画面进行变换。通过变量i,j来获得men, qiang, oxiang ,ren, jia, xiang(分别表示完成门、墙、箱子放在家中、人、家、箱子)的坐标来找到各个变量的位置,从而运用画图函数画出对应的图标。 void dayin() {

int i,j;

for(i=0;i<=12;i++) for(j=0;j<=16;j++) if(fuben[i][j]==jia&&v[i][j]==0) v[i][j]=jia; for(i=0;i<=12;i++) { for(j=0;j<=16;j++) {

if(v[i][j]==qiang){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_INTENSITY);printf("█");} else

if(v[i][j]==men){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE | FOREGROUND_RED);printf("П");} else

if(v[i][j]==oxiang){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_GREEN);printf("■");} else

if(v[i][j]==ren){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY|FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE|FOREGROUND_RED);printf("囧");} else

if(v[i][j]==jia){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY |FOREGROUND_GREEN | FOREGROUND_RED);printf("★");} else

if(v[i][j]==xiang){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE);printf("■");} else

{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUN

D_INTENSITY| FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);printf(" ");} }printf("\n");}

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY| FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);

printf("\n\n 关卡 %3d 步数 %3d 推箱子次数 %3d\n",num_guan,move_num,push_num); }

4 Wancheng()

Wancheng()函数在这个程序中的功能主要是判断游戏是否完成,其中定义了变量n来控制oxiang(进入了目标位置(家)的箱子)的个数,用fuben[i][j]==men来定义“完成门”,当n等于此关中箱子的个数且v[i][j]=men,即人的位置在“完成门”上的时候return(1)即玩家完成了这个一关,如果完成门在oxiang或者人不在完成门上则未完成。 int wancheng() { int i,j,n=0;

for(i=0;i<=12;i++) for(j=0;j<=16;j++) if(v[i][j]==oxiang) n=n+1; //n是对进入家的箱子计数 if(n==num_xiang) { if(tem==0) for(i=0;i<=12;i++) for(j=0;j<=16;j++) if(fuben[i][j]==men) v[i][j]=men; tem=tem+1; return 1; //正确 }

else if(v[door[0]][door[1]]==xiang) { v[door[0]][door[1]]=xiang; //错误 return 0; }

else if(v[door[0]][door[1]]!=ren) { v[door[0]][door[1]]=0; //错误 return 0;//程序结束 }

return 0; //错误 }

六 不足之处

由于技术等原因,有一些代码在效率上还有待提高,功能上有所不足。

七 程序特色

程序改变了传统的方式,实现了非黑框的窗口,并且实现了游戏人物的绘制以及运动,关卡的由易到难的逐级推进功能,让游戏变得更加有趣味有难度,从而吸引玩家玩这个游戏。

八 总结

通过这从课程,首先真正的感觉到了自己技术的提高,也认识到

了自己的不足和编写代码上的不熟练,在很多很多地方也需要花时间去练习,去提升。 然后,通过这一次课程设计的经验,我们能够发现,原来我们以前认为的非常难的一些东西在不懈的努力下也是可以完成的,“世上无难事,只怕有心人。” ,只要努力了,都会有收获,同时相信经过这一次课程设计,我们在以后的学习生活中一定会有更大的提升,更大的进步!

推箱子C课程设计报告.doc 将本文的Word文档下载到电脑

    精彩图片

    热门精选

    大家正在看

    × 游客快捷下载通道(下载后可以自由复制和排版)

    限时特价:7 元/份 原价:20元

    支付方式:

    开通VIP包月会员 特价:29元/月

    注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
    微信:fanwen365 QQ:370150219