C++扫雷课程设计.docx

上传人:b****5 文档编号:4640272 上传时间:2022-12-07 格式:DOCX 页数:16 大小:149.67KB
下载 相关 举报
C++扫雷课程设计.docx_第1页
第1页 / 共16页
C++扫雷课程设计.docx_第2页
第2页 / 共16页
C++扫雷课程设计.docx_第3页
第3页 / 共16页
C++扫雷课程设计.docx_第4页
第4页 / 共16页
C++扫雷课程设计.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

C++扫雷课程设计.docx

《C++扫雷课程设计.docx》由会员分享,可在线阅读,更多相关《C++扫雷课程设计.docx(16页珍藏版)》请在冰豆网上搜索。

C++扫雷课程设计.docx

C++扫雷课程设计

 

C++课程设计——扫雷

 

学院名称:

专业班级:

学生姓名:

指导教师姓名:

指导教师职称:

 

2010年7月

 

 

摘要

游戏业发展一日千里,该行业极大的影响和改变了人们的生活和娱乐方式,游戏为消费者提供丰富多彩的虚拟空间,使消费者可以自由自在的享受虚拟世界的乐趣,实现自己在现实生活着那个可能永远不能实现的梦想,满足了消费者的心理和精神需求。

扫雷游戏是Windows操作系统自带的一个小游戏,过去的几年里Windows操作系统历经数次换代,变得越来越庞大、复杂,但这个可爱的小游戏在任何版本的Windows操作系统里去却依然保持着原貌。

但几乎每个电脑使用者都接触过它,并且深爱着这款小游戏。

扫雷游戏是比较经典的一款小游戏,实现它的方法很多,可以用很多不同算法和语言实现,如C,C++,VB,JAVA等。

本论文研究的是以VisualC++6.0为开发环境,设计并开发一款扫雷游戏,其功能类似于Windows操作系统自带的扫雷游戏。

论文首先介绍了制作游戏的整体思路及整个游戏设计的流程规划,然后介绍了雷区的布置及地雷随机产生的实现方法;重点介绍了在游戏过程中各事件的处理,其中又以鼠标事件和清除未靠近地雷区方块这两方面最为最要,鼠标事件是利用鼠标所发出的信息了解使用者的意图,进而做出相对应的动作,而清除未靠近地雷区方块由于引进了“递归”这个概念而使其简单化。

 

第一章引言

1.1课题背景及意义

当前随着计算机的深入普及,越来越多的人有了个人电脑,人们运用计算机完成许多重要的工作,计算机在人们的生活中变的越来越来重要。

随着计算机的应用和发展计算机已经不单纯是一个工作工具,人们越来越重视计算机的娱乐性了,近年来游戏产业规模持续成长,全球每年游戏业总产值已经突破200亿美金,远远超越好莱坞电影产业以及音乐娱乐事业,而成为目前娱乐事业的最大主流。

不过游戏产业光鲜亮丽的背后,却也隐含着高风险、高成本的危机,显示游戏产业慢慢步入“微利时代”。

  目前整个游戏产业的运作模式已经跟好莱坞电影产业的运作模式相同,电影产业有制片、发行、宣传等分工,游戏产业亦同,由专业的游戏研发小组负责研发游戏,也有如微软这类国际级大厂负责游戏发行,甚至连“游戏制作人”也被培养成明星一样成为一种招牌.明确的游戏产业分工的确有助于游戏产业的规模发展与进化,但也无形中让游戏开发成本大增。

为了降低游戏开发成本,开发娱乐性强成本低的游戏就成为当前的主要课题,在这种趋势下各种小型的低成本的游戏软件应运而生。

在这其中,系统自带的小游戏也占据了相当重要的地位,与那些网络游戏和3D游戏相比,它有编写简单容易上手等特点,非常适合人们在完成工作的时候适当的娱乐要求。

这些小游戏大都是以益智和娱乐为目的,不仅给紧张工作的人们以放松,还可以让人们的大脑得到开发。

这些小游戏包括扫雷,弹球,纸牌等等。

而本课题就是扫雷游戏的设计。

1.2VisualC++发展概况

VisualC++是一个功能强大的可视化软件开发工具。

自1993年Microsoft公司推出VisualC++1.0后,随着其新版本的不断问世,VisualC++已成为专业程序员进行软件开发的首选工具。

虽然微软公司推出了VisualC++.NET(VisualC++7.0),但它的应用的很大的局限性,只适用于Windows2000,WindowsXP和WindowsNT4.0。

所以实际中,更多的是以VisualC++6.0为平台。

VisualC++6.0不仅是一个C++编译器,而且是一个基于Windows操作系统的可视化集成开发环境(integrateddevelopmentenvironment,IDE)。

VisualC++6.0由许多组件组成,包括编辑器、调试器以及程序向导AppWizard、类向导ClassWizard等开发工具。

这些组件通过一个名为DeveloperStudio的组件集成为和谐的开发环境。

VisualC++之所以具有如此广泛的用途是因为它具有以下的特点:

(1)真正的面向对象编程,使开发人员不用加入太多的代码,加快了系统开发的速度。

(2)可视化的编程方法以及向导的功能,使开发人员不用加入太多的代码就可以开发出标准的Windows程序。

(3)数据访问的特性,允许对包括MicrosoftSQLServer和其他企业数据库在内的大部分数据库格式建立数据库和前端应用程序,以及可调整的服务器端部件等。

(4)通过ActiveX技术可使用其他应用程序提供的功能,例如MicrosoftWord字处理器、MicrosoftExcel电子数据表及其他Windows应用程序,甚至可直接使用VisualBasic创建的应用程序和对象。

(5)Internet功能强大,使用户很容易在应用程序内通过Internet或企业内部网(Intranet)访问文档和应用程序,或者创建Internet服务器应用程序。

(6)已完成的应用程序是真正的.exe文件,您可以自由发布。

1.3关于本课题

随着世界经济的长足发展和计算机技术的日益成熟,计算机被应用到人类活动的各个领域,各种应用软件也相继问世,这其中有相当一部分是游戏软件。

使用游戏软件自然是为了满足人们对娱乐性的要求,而有些软件大都采用3D设计对系统配置的要求较高。

在众多游戏软件中,也不乏一些小游戏的身影,它们对系统的配置要求较低。

能够满足人们对娱乐性的需求,是人们在完成工作娱乐时候的最好选择。

现在越来越多的人投入到这种小游戏的开发当中,它已经成为一类必不可少的游戏软件。

在各种操作系统中都附带了一些小的游戏,而这些游戏也成为电脑用户软件中不可或缺的一部分。

作为本系统的开发工具,MicrosoftVisualC++6.0成为首选。

它具有可视化的编程界面、详细的提示、以及完善的帮助文档,使得软件开发人员感到无比的亲切感。

 

第二章游戏的总体分析与设计

2.1游戏功能简介

当前各种游戏软件层出不穷。

因为游戏的开发成本非常大,所以游戏的开发具有一定的风险性,但是一些小游戏的开发具有成本小,编写简单的优势,所以这些小游戏在游戏开发中也占有一席之地。

在这类小游戏中包括益智类游戏,它以画面精美游戏方法简单等特点得到大家的认可。

成为人们在工作之余不可或缺的好伙伴。

针对真种情况我用VC编写了扫雷这款小游戏。

下面对该游戏的功能做个简单的介绍。

扫雷游戏的基本功能:

点击鼠标左键于未知区域,如果未知区域有雷,游戏停止,显示所有的地雷。

如果没雷,则显示周围雷数,如果周围没雷,则再查看周围八个区域是否有雷直到有雷为止并显示,这其实是一个递归过程。

 点击鼠标右键于未知区域,则将其置为有雷而不管是否真的有雷。

可选择初、中、高三级并可自定义雷数和区域大小。

  雷区右下角显示总雷数减去被标明有雷区域的数目。

  雷区右下角显示扫雷的时间。

将雷全部扫清后或失败后显示一对话框。

2.2设计构想

相信大多数使用Windows操作系统的使用者,对这款游戏都不陌生。

这款游戏不止操作简单,规则也不难,再加上游戏速度的控制机制得宜,让整个游戏在操作过程中充满了快乐与紧张的气氛。

除了游乐当中能带给使用者快乐之外,游戏的设计内容无形中也不断训练使用者的逻辑思考能力,对于依靠高度脑力工作的现代人,都可以通过这个游戏,不时的检验一下自己,所以我们不难发现,在各种可携带的电子产品上都有这款游戏的踪影。

在设计之前,我们先来了解这款游戏的规则:

在不掀开任何藏有地雷的方块情况下,以最快的速度找出所有的地雷。

如果在掀开方块的过程中,不小心翻开(踩到)藏有地雷的方块,则宣告失败(游戏结束),惟有将所有不含地雷的方块掀开,游戏才算成功。

游戏的操作方面主要以鼠标为主,当鼠标指针对准未翻开的方块按下左键时即表示翻开方块,当鼠标指针对准未翻开的方块按下右键时即表示标示或疑示地雷,反复按下右键则方块会以未标示→标示→疑似三者关系不断循环。

游戏者可以通过地雷区内的数字提示了解以数字为中心的其周边八个方格内所含的地雷数,假若翻开的方块显示数字“3”,则表示以其为中心的周边方块内藏有3个地雷。

当按下的方块不是地雷,且周边八个方块也都没有地雷时,方块会以被翻开方块的八个方向将空白方块翻开。

2.3流程规划

流程规划大致上可以分为三个部分,分别为:

画面初始、游戏者按下第一个方块和为非地雷方块时展开。

画面初始时,以游戏者最后一次设定的地雷区大小为范围画出地雷区,当游戏者按下第一个方块时产开始计时,接着就是如何判断按下的方块是非地雷时的处理,这也是整个游戏的技术核心,我们可以通过递归的观念来检查周边的方块是否含有地雷及是否继续往外翻开,直到踩到雷或者游戏胜利为止。

 

第三章扫雷游戏的具体实现过程

3.1扫雷游戏模块的实现

扫雷游戏的开发主要包括两大部分:

一个部分是布雷,该部分主要将雷随机布置在游戏区域内,以避免出现相同的雷区布置地图。

另一部分是扫雷,该部分包括判断鼠标左键点击某区域该区域是否是雷,如果是雷该如何操作,如果不是雷该如何操作,鼠标右键点击某区域时如果判断该区域是雷则加以标记,如果不是雷也加以标记,以及当鼠标双击某区域时,判断与该区域相邻的其它8个区域是否是雷并做一个标记。

下面首先介绍第一部分之一——扫雷主窗体创建。

3.1.1扫雷游戏主窗体的创建

启动VisualC++6.0后,选择新建工程,VisualC++6.0提供了用户可能需要的各种类型的应用程序模板。

如果是这种情况,选择MFCAppWizard(exe)项目,输入工程名称和位置,将创建一个新的工程如下:

选择基于Singledocument:

其它的默认,建立新的工程。

下面介绍一下如何创建:

1.资源视图中添加扫雷所需要的位图

2.在窗口类定义的前面添加下面两个新建的类

//创建一个雷位类

classOneMine

{public:

OneMine();

voidInitOneMine();//初始化一个雷位

boolIsMine;//是否是雷

boolOpened;//是否已经打开

boolMark;//是否已经被标记

shortAroundMines;//周边的雷数

shortstate;};//显示图形号

//创建雷区类

classMines

{public:

boolGameOver;//扫雷是否结束

shortTimes;//扫雷所用的时间

shortRows,Cols;//雷区的行数、列数

shortMinesCount;//布设雷的数量

shortMarkMines;//标对雷的数量

shortVirtualMines;//标记为雷的数量

OneMine*pos[52][32];//存放雷对象的数组指针

Mines();

~Mines();

voidReInitMine(shortrow,shortcol,shortmines);//重新初始化雷区

voidLayOneMines();//布置一个地雷

voidCalculateAroundMine(intx,inty);//计算每个雷周边的雷数

voidShowOneMine(intx,inty);//显示一个雷位

voidShowAllMine();//显示所有雷位

voidOpenOneMine(intx,inty);//打开一个雷位

voidMarkOneMine(intx,inty);};//标记一个雷位

3.在窗口类中添加雷区对象:

MinespMine;

4.在OnDraw(CDC*pDC)函数中添加显示雷区功能:

if(pView==NULL)pView=this;//给窗口类指针赋值

pMine.ShowAllMine();//显示雷区

5.在窗体类视图上单击鼠标右键,选择AddWindowsMessageHandler

单击WM_LButtonDown,然后再单击“AddHandler”按钮,添加鼠标左键处理函数

单击WM_RButtonDown,然后再单击“AddHandler”按钮,添加鼠标右键处理函数

6.在鼠标左键处理函数OnLButtonDown(UINTnFlags,CPointpoint)中添加下面代码:

intx=point.x/16+1,y=point.y/16+1;//计算坐标

pMine.OpenOneMine(x,y);//打开该位置地雷

7.在鼠标右键处理函数OnRButtonDown(UINTnFlags,CPointpoint)中添加下面代码:

intx=point.x/16+1,y=point.y/16+1;//计算坐标

pMine.MarkOneMine(x,y);//该位置地雷做标记

3.1.2主界面控制菜单的设计

接下来回到资源编程界面,编写菜单资源,用来控制扫雷的过程,难度选定,以及自定义难度窗口等。

(1)设置菜单包含:

开始,初级,中级,高级,自定义。

(2)帮助菜单获取该软件的版本信息。

如下:

将菜单添加到主界面,至此主窗体基本创建完毕。

运行如下:

3.2扫雷游戏核心-----布雷算法设计

再窗口代码中添加如下代码:

//雷位构造函数

OneMine:

:

OneMine()

{InitOneMine();}

//重新初始化一个雷位

voidOneMine:

:

InitOneMine()

{IsMine=Opened=Mark=false;AroundMines=0;state=-1;//state=-1为该雷未打开,也未标记,state=1到8为该雷位周边地雷数

//state=9为该雷位做了标记

//state=10为该雷位有疑问

//state=11为该雷位标错了地雷

//state=13为真雷}

//雷区构造函数

Mines:

:

Mines()

{for(inti=0;i<32;i++)

for(intj=0;j<52;j++)

pos[j][i]=newOneMine();

ReInitMine(12,20,30);}

//雷区析构函数

Mines:

:

~Mines()

{for(inti=0;i<32;i++)

for(intj=0;j<52;j++)

deletepos[j][i];}

//重新初始化雷区

voidMines:

:

ReInitMine(shortrow,shortcol,shortmines)

{inti,j;

GameOver=false;Times=0;

Rows=row;Cols=col;

MinesCount=mines;MarkMines=0;VirtualMines=0;

for(i=1;i<=Rows;i++)//把所有的雷位地雷清除

for(j=1;j<=Cols;j++)

pos[j][i]->InitOneMine();

srand((unsigned)GetTickCount());//初始化产生随机数函数

for(i=0;i

LayOneMines();//布置地雷

for(i=1;i<=Rows;i++)//计算每个雷位周边的雷数

for(j=1;j<=Cols;j++)

CalculateAroundMine(j,i);}

//布一个地雷

voidMines:

:

LayOneMines()

{intm,n;

do{

m=rand()%Cols+1;n=rand()%Rows+1;//随机产生雷位坐标

}while(pos[m][n]->IsMine);

pos[m][n]->IsMine=true;}

当然,还得添加代码用来在游戏区域显示随机布置的雷和周边情况,在函数中添加如下代码:

//计算一个雷位周边的地雷数

voidMines:

:

CalculateAroundMine(intx,inty)

{intmines=0;

for(inti=x-1;i<=x+1;i++)

for(intj=y-1;j<=y+1;j++)

mines=mines+pos[i][j]->IsMine;

pos[x][y]->AroundMines=mines;}

//显示一个雷位图

voidMines:

:

ShowOneMine(intx,inty)

{CBitmapbmp;

bmp.LoadBitmap(pos[x][y]->state+1000);

CDCdcMemory,*dc;

dc=pView->GetDC();//在内存中创建一个位图兼容设备

dcMemory.CreateCompatibleDC(dc);

dcMemory.SelectObject(&bmp);//将图片选入兼容设备

//将兼容设备的内容copy到屏幕设备中,实现真正的Paint

dc->BitBlt(x*16-16,y*16-16,16,16,&dcMemory,0,0,SRCCOPY);}

//显示所有雷位图

voidMines:

:

ShowAllMine()

{for(inti=1;i<=Rows;i++)

for(intj=1;j<=Cols;j++)

ShowOneMine(j,i);}

3.3扫雷鼠标事件的处理

(1)首先,设计雷区和非雷区的判断算法。

扫雷时需要判断每个格子的状态,可事先为格子设定一些状态,使之对应不同的BOOL值或整数值。

在二维、三维游戏里,有一种简单的构造地图的方法,即将地图划分为m*n的规格格子,使每一个格子对应二维数组中的一项,当鼠标单击时,通过找出鼠标点击区域,找到相应的格子,判断格子状态来替换相应的位图。

具体算法思想如下:

A.在应用程序的客户区划分一块区域,将该区域划分为n*m相同大小的格子;

B.将每一个格子的状态对应到二维数组的相应项上;

C.当鼠标点击某一块区域时,首先判断是否在各种区域,然后再通过鼠标的坐标找到相应的格子;

D.查询格子的状态,从而调用相应的位图进行位图替换;

(2)鼠标左键事件的处理。

分两种情况:

A.当相应区域不是雷区时,挖开区域,并且若能据此判断周围区域也不是雷区则将周围相应区域也挖开;

B.当区域是雷区时,则界面中所有的雷区同时“炸开“:

第一步先显示一个提示框,第二部当提示框关闭时,所有非雷区显示出来。

C.鼠标在笑脸图片上,单击可以重新开始。

(3)对单击鼠标右键事件处理

第一次用右键单击某个区域时,改区域上插上一面小红旗,此时单击左键没有任何变化,第二次用右键单击时恢复原状。

(4)双击左键事件处理

在展开的区域,并且已经确定了周围的雷数,双击可以叠加展开非雷区域,以减少用户的单击操作。

基于以上的思想,在VC++6.0中进行“扫雷”的主要编码如下:

//打开一个雷位

voidMines:

:

OpenOneMine(intx,inty)

{OneMine*p=pos[x][y];if(x>Cols||x<1||y>Rows||y<1)return;//如果点的位置不在雷区,则返回

if(GameOver)return;//如果扫雷结束,则返回

if(p->Opened)return;//如果该位置已经打开,则返回

if(p->Mark)return;//如果该位置已经标记了,则返回

if(p->IsMine)//如果该雷位是地雷

{for(inti=1;i<=Rows;i++)//找出所有的地雷,并显示出来

for(intj=1;j<=Cols;j++)

if(pos[j][i]->IsMine)

{pos[j][i]->state=12;ShowOneMine(j,i);}

elseif(pos[j][i]->state==9)

{pos[j][i]->state=11;ShowOneMine(j,i);}

p->state=13;ShowOneMine(x,y);GameOver=true;

return;}

else//如果该雷位不是地雷

{p->Opened=true;p->state=p->AroundMines;ShowOneMine(x,y);

if(p->AroundMines==0)/*如果该雷位周边的雷数为零,打开周边的雷位,采用递归调用的方法*/

{if(x!

=1)OpenOneMine(x-1,y);//打开左边

if(x!

=Cols)OpenOneMine(x+1,y);//打开右边

if(y!

=1)OpenOneMine(x,y-1);//打开上边

if(y!

=Rows)OpenOneMine(x,y+1);//打开下边

if(x!

=1&&y!

=1)OpenOneMine(x-1,y-1);//打开左上

if(x!

=1&&y!

=Rows)OpenOneMine(x-1,y+1);//打开左下

if(x!

=Cols&&y!

=1)OpenOneMine(x+1,y-1);//打开右上

if(x!

=Cols&&y!

=Rows)OpenOneMine(x+1,y+1);//打开右下}

}

}

//标记一个雷位

voidMines:

:

MarkOneMine(intx,inty)

{OneMine*p=pos[x][y];if(x>Cols||x<1||y>Rows||y<1)return;//如果点的位置不在雷区,则返回

if(GameOver)return;//如果扫雷结束,则返回

if(p->Opened)return;//如果该位置已经打开,则返回

switch(p->state)

{case-1:

{p->state=9;p->Mark=true;VirtualMines++;

if(p->IsMine)MarkMines++;

break;}

case9:

{p->state=10;p->Mark=true;VirtualMines--;

if(p->IsMine)MarkMines--;

break;}

case10:

{p->state=-1;p->Mark=false;break;}

}

ShowOneMine(x,y);

if(MarkMines==MinesCount)

{:

:

MessageBox(NULL,"恭喜您,扫雷成功了!

","提示信息",MB_OK);

this->GameOver=true;}

}

3.4扫雷其它处理

3.4.1难度设置菜单消息处理

菜单项中包含扫雷难度设置,如初

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

当前位置:首页 > 高中教育 > 高中教育

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

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