北京工业大学 c语言课程设计 报告.docx

上传人:b****6 文档编号:5942010 上传时间:2023-01-02 格式:DOCX 页数:43 大小:133.08KB
下载 相关 举报
北京工业大学 c语言课程设计 报告.docx_第1页
第1页 / 共43页
北京工业大学 c语言课程设计 报告.docx_第2页
第2页 / 共43页
北京工业大学 c语言课程设计 报告.docx_第3页
第3页 / 共43页
北京工业大学 c语言课程设计 报告.docx_第4页
第4页 / 共43页
北京工业大学 c语言课程设计 报告.docx_第5页
第5页 / 共43页
点击查看更多>>
下载资源
资源描述

北京工业大学 c语言课程设计 报告.docx

《北京工业大学 c语言课程设计 报告.docx》由会员分享,可在线阅读,更多相关《北京工业大学 c语言课程设计 报告.docx(43页珍藏版)》请在冰豆网上搜索。

北京工业大学 c语言课程设计 报告.docx

北京工业大学c语言课程设计报告

扫雷

 

学号_____110703xx___

姓名_____xxx______

指导教师______xx______

2011年12月

1需求分析3

1.1功能与数据要求3

1.1.1游戏功能介绍4

1.2界面需求4

1.3开发与运行环境需求6

2概要设计7

2.1主要数据结构8

2.2程序总体结构9

2.2.1函数调用说明9

2.2.2其余子函数说明10

3详细设计11

4测试33

4.1鼠标响应测试33

4.2游戏各项数据测试34

4.3游戏时间测试34

4.4游戏界面跳转测试34

5用户手册35

6总结提高36

 

1需求分析

游戏名称:

挖雷游戏(MineSweeper)这是一款益智动脑游戏。

玩家只要利用鼠标点击,将随机出现在游戏区中的所有雷挖出来,即可获得游戏胜利。

1.1功能与数据要求

基本功能:

1.初始界面由控制区和游戏区两部分组成。

游戏区有一个9*9的深颜色不透明方阵,内有若干个不可见的地雷,随机分布在方格中。

随机产生雷的同时随机产生几个“秘密武器”:

防雷服或探测仪,如果挖到一个防雷服,挖雷员增加一条命;如果挖到探测仪,使用探测仪探测时,点击方格,可显示本方格以及周围八个方格里是否有雷。

使用探测仪的方法是:

用鼠标右键单击方格。

一个探测仪只能使用一次。

2程序启动后,单击“开始”按钮,则从键盘输入用户名,然后游戏开始。

3用鼠标选中任一方格,如果不是地雷,方格颜色变为浅色;如果是“秘密武器”,方格变为浅色同时工具可以使用,并在游戏信息区显示“秘密武器”的标志(例如:

红色的圆圈表示防雷服,等等)及个数;如果是地雷则爆炸,减少一条命(也即减少一个防雷服),所有命消耗完毕则游戏结束。

4每个挖雷员初始分数为0。

每标记一个非雷方格得一分。

在控制区显示当前挖雷员的当前得分。

5游戏设置时间设置,或称生命值。

时间用完则游戏结束。

6游戏可有以下结束方式:

成功结束:

当前所有非雷区都被标出,程序自动把有雷的方格标为红色,游戏结束,并显示当前玩家分数。

失败结束:

情况1:

当时间全部用完,而界面仍有非雷方格未标出,则游戏结束。

情况2:

遇到雷爆炸并已经用完所有防雷服,则游戏结束。

情况3:

游戏过程中,按结束按钮,强行终止。

7设置游戏的排行榜,显示玩家排名。

 

拓展功能:

1增加时间显示。

每一局限定在同一个预先设置的时间段内完成,动态记时并显示,当某一局到达限定时间,则游戏结束(但保留主界面)。

2探测仪功能增加为点击本格翻开周围的8个格子。

3当游戏成功结束后,可以进行下一局游戏。

4设计一种方法,可以显示非雷方格周边的地雷数。

 

1.1.1游戏功能介绍

(1)通过visualstudio2010进入扫雷游戏界面。

(2)进入游戏控制区域。

点击开始,输入用户名,开始计时,同时游戏开始。

(3)成功完成游戏的标志是:

在规定时间内,挖开所有的非雷方格。

三种情况视为失败:

情况1:

当时间全部用完,而界面仍有非雷方格未标出,则游戏结束。

情况2:

遇到雷爆炸并已经用完所有防雷服,则游戏结束。

情况3:

游戏过程中,按结束按钮,强行终止。

1.2界面需求

游戏欢迎界面中:

程序运行后,即出现欢迎界面,并显示作者姓名学号,采用闪动字体

的形式,使画面生动,按任意键进入游戏。

 

游戏初始界面:

游戏界面分为控制区,信息区,游戏区,此时可以点击开始,进入游戏。

游戏进行中:

游戏以失败结束画面:

1.3开发与运行环境需求

开发环境:

Visualstudio2010

运行环境:

Win7

 

2概要设计

游戏流程图:

 

2.1主要数据结构设计:

2.1.1二维数组

1、记录每个方格中信息的二维数组mine[9][9]

2、记录每个方格中信息作为备用的二维数组mine2[9][9]

3、记录每个方格中信息作为备用的二维数组mine3[9][9]

2.1.2全局变量

1intmine[9][9]

记录每个方格中信息的二维数组

2intmine2[9][9]

记录每个方格中信息作为备用的二维数组

3、intlife

记录该游戏进行中玩家生命值。

4、intmark

当前玩家的得分

5、time_tstart

初始时间

6、time_tnow

当前时间

7、inttime1

记录暂停时间

8、intb;

用于游戏信息区探测仪数量变化统计

9、intk;

用于游戏信息区防雷服数量变化统计

10、intn;

探测仪数量

11、intq;

用于游戏信息记录中玩家信息的记录

12、typedefstructrankinglist{

charname[100];

intscore;

}INFO;

玩家信息结构体,用于记录玩家信息。

13、INFOs[10];

定义排行榜最大信息保存数为10

2.2程序总体结构:

2.2.1函数调用说明

main()

功能:

主函数

调用:

jiemian();

hitKS();

minefield();

mousemsg();

gameover();功能:

游戏失败结束

pause();功能:

暂停

closeJM();功能:

关闭界面

jiemian()

功能:

绘制游戏界面

调用:

Life();

Mark();

welcome();

hitKS()

功能:

点击开始

调用:

Start();

mousemsg()

功能:

鼠标响应

调用:

time();

zuojianleishutongji(inti,intj);

zuojianFLF_TCY(inti,intj);

Mark();

Life();

gamewin();

pause()

功能:

暂停游戏

调用:

mousemsg();

pause();

closeJM()

功能:

关闭界面

调用:

goodbye();

 

2.2.2其余子函数功能概要说明

Start()

功能:

接收玩家姓名

Life()

功能:

刷新游戏生命值

Mark()

功能:

刷新游戏当前得分

time()

功能:

记录游戏用时

zuojianleishutongji(inti,intj)

功能:

左键雷数统计

zuojianFLF_TCY(inti,intj)

功能:

左键点出防雷服,探测仪

gamewin()

功能:

游戏胜利结束界面

gameover()

功能:

游戏失败结束界面

minefield()

功能:

初始化方格信息

welcome();

功能:

浮现欢迎界面

goodbye();

功能:

退出游戏界面

 

3详细设计

3.1welcome函数功能:

产生一个欢迎界面,显示游戏名,作者。

使用户界面更加友好。

voidwelcome()

{

charbuf12[100]="设计人:

11070322丛义昊";

//输出屏幕提示

cleardevice();

setcolor(YELLOW);

setfont(90,0,"黑体");

outtextxy(160,50,"挖雷游戏");

setcolor(WHITE);

setfont(16,0,"宋体");

outtextxy(240,240,buf12);

 

//实现闪烁的“按任意键继续”

intc=255;

while(!

kbhit())

{

setcolor(RGB(c,0,0));

outtextxy(255,400,"按任意键进入游戏");

c-=8;

if(c<0)c=255;

Sleep(20);

}

getch();

cleardevice();

}

3.2界面函数功能:

构造游戏初始界面,包括了游戏界面,字体,线,填充颜色,字符输出等各方面的设计。

voidjiemian()

{

initgraph(640,480);//欢迎界面

welcome();

initgraph(900,650);//初始化图形方式

inti,j;//定义变量

charbuf1[100]="开始";

charbuf2[100]="暂停";

charbuf3[100]="结束";

charbuf4[100]="防雷服:

";

charbuf5[100]="探测仪:

";

setlinestyle(PS_SOLID,NULL,3);//更改线的粗细为3

setfont(20,0,"黑体");//字体设为黑体

cleardevice();

setfillstyle(LIGHTGRAY,SOLID_FILL);

rectangle(100,100,800,600);

rectangle(100,100,350,450);//游戏控制区

rectangle(100,450,350,600);//游戏信息区

rectangle(150,150,300,200);//开始框

rectangle(150,250,300,300);//暂停框

rectangle(150,350,300,400);//结束框

outtextxy(210,167,buf1);//指定位置输出字符串

outtextxy(210,267,buf2);

outtextxy(210,367,buf3);

outtextxy(130,460,buf4);

outtextxy(130,480,buf5);

Life();//初始化生命显示

Mark();//初始化得分显示

setfillstyle(BLUE,SOLID_FILL);

for(i=0;i<9;i++)//画9x9的雷阵并涂色

for(j=0;j<9;j++){

rectangle(400+i*40,170+j*40,400+(i+1)*40,170+(j+1)*40);

floodfill(400+i*40+6,170+j*40+6,WHITE);

}

}

3.3hitKS函数功能:

控制开始键的响应,达到只有鼠标左键点击开始按钮才有反应的效果。

inthitKS()//点击开始,进入游戏

{

MOUSEMSGm=GetMouseMsg();

while(true)

{

if(MouseHit())

m=GetMouseMsg();//获得鼠标信息

switch(m.uMsg)

{

caseWM_LBUTTONDOWN:

{

if(m.x>150&&m.x<300&&m.y>150&&m.y<200)//点击到开始按键,否则无反应

{

Start();

return0;

}

}

default:

continue;

}

}

}

3.4Start函数功能:

在hitKS函数执行后,跳出接受用户名的框,接受玩家从键盘输入的玩家名,并回显到游戏信息区。

voidStart()

{

chars1[100];//定义字符串缓冲区,并接收用户输入

chars2[100];

InputBox(s1,100,"请输入玩家姓名:

");//弹出接收用户名的框

sprintf(s2,"玩家名:

%s",s1);

outtextxy(130,560,s2);//指定位置输出玩家名

now=time(NULL);//初始化当前时间

}

3.5time函数功能:

通过和鼠标响应嵌在一个永真循环中,反复调用,达到不断刷新游戏信息区时间显示的效果。

voidtime()

{charbuf1[100];

start=time(NULL);

sprintf(buf1,"共70秒,已用时:

%d",time1+(int)difftime(start,now));

outtextxy(130,540,buf1);//不断刷新当前时间

}

3.6minefield函数功能:

初始化雷阵方格信息,通过随机数种子控制产生不同的随机数,按照雷,防雷服,探测仪的顺序随即分配到81个方格中。

voidminefield()

{

inti,j,mineNUM=10,flfNUM=5,tcyNUM=5;//初始化雷数,探测仪数,防雷服数

srand((int)time(0));//产生随机数

do{

i=rand()%9;

j=rand()%9;//随机位置产生雷

mine[i][j]=1;

mine2[i][j]=1;

mine3[i][j]=1;

mineNUM--;

}

while(mineNUM>0);

do{

i=rand()%9;//随机位置产生防雷服

j=rand()%9;

if(mine[i][j]==0){

mine[i][j]=2;

mine2[i][j]=2;

mine3[i][j]=2;

flfNUM--;}

}

while(flfNUM>0);

do{

i=rand()%9;//随机位置产生探测仪

j=rand()%9;

if(mine[i][j]==0){

mine[i][j]=3;

mine2[i][j]=3;

mine3[i][j]=3;

tcyNUM--;}

}

while(tcyNUM>0);

}

3.7LifeMark函数功能:

由于life,mark为全局变量,将LifeMark函数嵌套在任意一个可以影响life,mark值变化的子函数中,即可实现游戏信息区生命值,得分的实时更新。

voidLife()//刷新游戏信息区的生命值显示

{

charbuf6[100];

sprintf(buf6,"生命值:

%d",life);

outtextxy(130,500,buf6);

}

voidMark()

{

charbuf8[100];

sprintf(buf8,"当前得分:

%d",mark);

outtextxy(130,520,buf8);//输出当前得分

}

3.8pause函数功能:

嵌套在mousemsg函数中,通过用户点击暂停键区域,即可实现结束mousemsg函数的作用,在主函数中,由于pause函数在mousemsg之后,所以紧接着执行pause函数,最终通过再次点击暂停判断条件中的两个函数相互调用,达到可以反复暂停的效果。

if(m.x>150&&m.y>250&&m.x<300&&m.y<300){

//点击暂停

time1=time1+(int)difftime(start,now);

return0;}

intpause()

{

if(life<=0||time1+(int)difftime(start,now)>=70)

{

return0;

}

if(mark>=71)

return0;

MOUSEMSGm=GetMouseMsg();

while(true)

{

if(MouseHit())

m=GetMouseMsg();

switch(m.uMsg)//达到暂停游戏效果

{

caseWM_LBUTTONDOWN:

{

if(m.x>150&&m.y>250&&m.x<300&&m.y<300)

now=time(NULL);

mousemsg();//函数相互调用

pause();

}

default:

continue;

}

}

}

3.9mousemsg函数功能:

此函数包含一个大的永真循环,是游戏设计的关键部分包括1.刷新时间显示2左键点击雷阵方格,开始、暂停、结束键的响应3右键点击使用探测仪翻开周围格子的响应4通过时间,得分,生命来判断游戏是否结束(成功or失败)。

intmousemsg()

{

inti,j,mineNUM=0;

MOUSEMSGm=GetMouseMsg();

charbuf7[100];

while(true)//大循环

{

time();//调用时间函数

if(time1+(int)difftime(start,now)>=70)

return0;//时间到,游戏以失败结束

if(MouseHit())//获取鼠标信息

m=GetMouseMsg();

switch(m.uMsg)

{

caseWM_LBUTTONDOWN:

{

setfillstyle(LIGHTBLUE,SOLID_FILL);

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

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

{

if(m.x>(400+i*40)&&m.x<(440+i*40)&&m.y>(170+j*40)&&m.y<(210+j*40))

{

zuojianleishutongji(i,j);//调用雷数统计

if(mine[i][j]==1)

{

circle(420+i*40,190+j*40,15);

life--;//踩雷生命减一

Life();//刷新生命值

mine[i][j]=6;//赋另值,防止重复点击

setfillstyle(BLACK,SOLID_FILL);

if(k>0)

{

bar(191+(k-1)*20,459,209+(k-1)*20,475);//游戏信息区防雷服减少显示一个

k--;

}

setfillstyle(LIGHTBLUE,SOLID_FILL);

floodfill(406+i*40,176+j*40,WHITE);

if(life<=0)//判断游戏失败的条件

return0;

}

zuojianFLF_TCY(i,j);//调用防雷服,探测仪的显示函数

floodfill(406+i*40,176+j*40,WHITE);//将格子颜色变浅

}

 

}

if(m.x>150&&m.y>250&&m.x<300&&m.y<300){

//点击暂停

time1=time1+(int)difftime(start,now);

return0;

}

if(m.x>150&&m.y>350&&m.x<300&&m.y<400){

//点击结束

life=0;

return0;

}

if(mark>=71)//胜利条件之一,成功翻开所有格子

{gamewin();

return0;}

break;

}

由于四边及四角的特殊性,需要考虑到mine[i][j]中i,j的具体取值,所以需要分类讨论,鉴于有雷格子的特殊性,需要将其翻过后另赋为一个特殊值6,以便与翻过的其他格子区分开。

caseWM_RBUTTONDOWN:

{//右键为探测仪功能,翻开本格周围9个格子,并显示雷数,标识雷的位置

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

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

{

if(m.x>(400+i*40)&&m.x<(440+i*40)&&m.y>(170+j*40)&&m.y<(210+j*40))

{

if(n>0)//当有探测仪时,点击生效

{

if(b>0)//控制游戏信息区的防雷服显示

{setfillstyle(BLACK,SOLID_FILL);

bar(190+(b-1)*20,477,211+(b-1)*20,497);

b--;//防雷服显示减一个

}

if(mine[i][j]==0)

{setfillstyle(LIGHTBLUE,SOLID_FILL);

floodfill(406+i*40,176+j*40,WHITE);

mine[i][j]=5;

mark++;

}

if(mine[i][j]==2)

{

setfillstyle(LIGHTBLUE,SOLID_FILL);

floodfill(406+i*40,176+j*40,WHITE);

setfillstyle(GREEN,SOLID_FILL);

circle(200+k*20,467,7);

floodfill(201+k*20,468,WHITE);

circle(420+i*40,190+j*40,15);

floodfill(421+i*40,191+j*40,WHITE);

mine[i][j]=5;

life++;

mark++;

Life();

k++;

}

if(mine[i][j]==3)

{

setfillstyle(LIGHTBLUE,SOLID_FILL);

floodfill(406+i*40,176+j*40,WHITE);

setfillstyle(RED,S

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

当前位置:首页 > 自然科学

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

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