欢迎来到沃文网! | 帮助中心 分享知识,传播智慧!
沃文网
换一换
首页 沃文网 > 资源分类 > DOC文档下载
 

用VC++设计与实现扫雷系统

  • 资源ID:20091       资源大小:138.92KB        全文页数:18页
  • 资源格式: DOC        下载权限:游客/注册会员/VIP会员    下载费用:10积分 【人民币10元】
快捷注册下载 游客一键下载
会员登录下载
三方登录下载: QQ登录   微博登录  
下载资源需要10积分 【人民币10元】
邮箱/手机:
温馨提示:
支付成功后,系统会自动生成账号(用户名和密码都是您填写的邮箱或者手机号),方便下次登录下载和查询订单;
支付方式: 微信支付    支付宝   
验证码:   换一换

加入VIP,免费下载资源
 
友情提示
2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,既可以正常下载了。
3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰   

用VC++设计与实现扫雷系统

用VC实现扫雷游戏程序学生姓名尹一笑指导老师颜宏文摘要本课程设计实现类似于Windows操作系统自带的扫雷游戏。在课程设计中,系统开发平台为WindowsXP,程序设计语言采用VisualC,程序运行平台为Windows2000/XP。在程序设计中,把整个雷区看成一个二维数组,把雷方块定义为具有所在雷区二维数组的行和列、当前状态、方块属性、历史状态的结构体,采用了MFC机制解决问题的方法。整个游戏程序包括了布雷、扫雷过程和结果三个阶段,在处理鼠标响应事件中伴随着GDI绘图。程序通过调试运行,实现了设计目标,能够同时满足扫雷游戏初学者和高手的需要。关键词扫雷游戏程序设计VisualC6.0GDI绘图扫雷游戏历史VisualC6.0GDI原理基础2需求分析1功能概述扫雷游戏的游戏界面如图1.1所示。在这个界面中,由众多面积均等的小方块所组成的区域称之为雷区,雷区的大小由用户设置的游戏等级决定。图1.1游戏开始时,系统会在雷区的某些小方块中随机布下若干个地雷。安放好地雷的小方块称之为雷方块,其他的称之为非雷方块。部署完毕后,系统会在其他非雷方块中填充一些数字。某一个具体数字表示与其紧邻的8个方块中有多少雷方块。玩家可以根据这些信息去判断是否可以打开某些方块,并把认为是地雷的方块打上标识。当玩家将所有地雷找出后,其余的非雷方块区域都已打开,此时玩家标定地雷周围雷数提示未知区玩家标定未知游戏结束。在游戏过程中,一旦错误地打开了雷方块则立即失败,游戏结束;当玩家标识的地雷数超过程序设定,虽然打开了全部其余方块,游戏仍然不会结束。在游戏开始后,雷区上方有两个计数器。右边的计数器显示用户扫雷所花费的总时间,以秒为单位;左边的计数器显示当前还剩余多少个雷方块。本课程设计实现类似于Windows操作系统自带的扫雷游戏。游戏需要提供一个菜单栏,上面有不同的相关选项,如游戏的开始、难度设置、退出等。按功能将游戏区域分成两个区域雷区和提示区。提示区包括两个计数器和一个按键操作结果图像提示。游戏过程中,当玩家用鼠标点击相应的方块,程序就会作出相应的鼠标响应事件,并伴随着GDI绘图,而众多鼠标事件的处理,都是围绕着实现扫雷程序的算法而衍生的。系统总框图及每个模块的设计分析2、框架的搭建3、菜单的制作4、布雷,扫雷核心算法的实现5、界面的制作3总体设计3.1游戏框架的搭建3.1.1工程项目的创建利用应用程序向导创建一个名称为Mine的工程项目。由于不需要诸如工具栏、状态栏等功能,并且扫雷游戏的框架是不允许改变窗口大小的,所以在向导的第四步里面把所有的选项置空,然后点击“Advanced”按钮,在弹出的对话框中选中“WindowsStyles”选项卡,将“Maximizebox”项置空,其他均使用默认设置。3.1.2框架的改造通过类向导添加一个继承于CFrameWnd的类,命名为CMineWnd,删除CMineDoc、CMineView和CAboutDlg类,将CMineWnd类代替CFrameWnd,让程序启动的时候以此窗口为主窗口予以显示。结果如图1.2。图1.23.2菜单的制作参考Windows自带的扫雷游戏,创建出“游戏”和“帮助”菜单,然后通过菜单资源编辑器设定菜单的功能选项,包括难度级别的选择、颜色和音效是否开启、扫雷英雄榜、使用手册、关于软件的信息等。具体的菜单选项分别如图1.3。3.2.1难度级别的选择不同的难度级别有不同的雷区大小和不同的布雷数目,所以通过宏定义预定义不同级别的横向方块数目、纵向方块数目和雷数。并将该宏定义放入新建的头文件“MineDefs.h”中。窗口除了雷区外至少还包括蓝色窗口边缘Frame_wide、白色的视觉效果区line_wide、3D的外壳边框3D_line_wide、雷区mine_area_wide等。于是还需要定义关于位置的宏变量。由于难度级别的不同,窗口大小也会随之改变,因此通过在CMineWnd类增加一个改变窗口大小的函数SizeWindow去实现。通过ClassWizard分别选择“初级”、“中级”和“高级”菜单资源ID,为它们添加处理函数OnMenuPrimary、OnMenuSecond、OnMenuAdvance。OnMenuAdvance的实现如下,另外两个类似。voidCMineWndOnMenuAdvance{m_uLevelLEVEL_ADVANCE;m_uXNumADVANCE_XNUM;m_uYNumADVANCE_YNUM;m_uMineNumADVANCE_MINENUM;SetCheckedLevel;InitGame;Invalidate;SizeWindow;}3.2.2雷区大小的自定义实现首先新建一个自定义雷区对话框资源IDD_DLG_CUSTOM,然后添加高度、宽度、雷数三个静态文本控件和三个对应的IDC_HEIGHT、IDC_WIDTH、IDC_NUMBER编辑框控件,最后将OK和Cancel按钮分别改名为“确定”和“取消”。如图1.3接着为该对话框创建CDlgCustom类,然后为三个编辑控件分别添加关联变量m_uHeight、m_uNumber、m_uWidth,最后为OK按钮创建命令消息处理函数OnOK,代码如下所示。voidCDlgCustomOnOK{UpdateData;ifm_uWidth30m_uWidth30;ifm_uHeight24m_uHeight24;ifm_uNumberm_uWidth*m_uHeightm_uNumberm_uWidth*m_uHeight-1;CMineWnd*pMineCMineWnd*AfxGetMainWnd;pMine-SetCustomm_uWidth,m_uHeight,m_uNumber;//TODOAddextravalidationhereCDialogOnOK;}3.2.3使用帮助的实现由于Windows自带有扫雷游戏,所以直接调用它的使用手。为“使用帮助”菜单选项创建命令消息处理函数OnMemuHelpUse,代码如下所示。voidCMineWndOnMemuHelpUse{//在命令行调用HH.,并输入参数NTHelp.CHM,//令其打开该文件,即Windows自带有扫雷游戏的是使用手册WincHHNTHelp.CHM,SW_SHOW;}3.2.4关于信息的实现voidCMineWndOnMemuAbout{ShellAboutthis-m_hWnd,扫雷,,NULL;}3.2.5扫雷英雄榜的实现首先创建两个对话框模板,一个用作当用户胜利结束游戏并打破历史记录后弹出的签名记录对话框模板IDD_DLG_NEWRECORD,另外一个是用以显示以往最高的游戏记录的对话框模板IDD_DLG_HERO。如图1.3和1.4。然后为IDD_DLG_HERO对话框模板创建CDlgHero类,分别为编辑框控件添加关联变量m_szBHolder、m_szBRecord、m_szEHolder、m_szERecord、m_szIHolder、m_szIRecord,并将Cancel按钮的ID和标题分别改为IDC_RESET和重新计分,三个静态文本标题设置为初级记录、中级记录、高级记录,最后为重新计分按钮创建命令消息处理函数OnReset和其他成员函数。对IDD_DLG_NEWRECORD对话框模板类似处理。3.3布雷,扫雷核心算法的设计与实现3.3.1算法的设计把整个雷区看成一个二维数组,a[i][j]周围的雷个数是由如下8个雷区决定的如果超出边界,应该再加以判断a[i-1][j-1],a[i-1][j],a[i-1][j1],a[i][],a[i][j1],a[i1][j-1],a[i1][j],a[i1][j1],在被展开时,检查周围的雷数是否与周围标示出来的雷数相等,如果相等则展开周围未标示的雷区。这样新的雷区展开又触发这个事件,就这样递归下去,一直蔓延到不可展开的雷区。3.3.2核心算法的实现整个游戏程序包含3个阶段布雷、扫雷过程和结果(并不是操作结果展示,而是在扫雷过程中,玩家通过与游戏交互后的操作结果展示)。首先定义雷方块的数据结构,具体描述如下所示。typedefstruct{UINTuRow;//所在雷区二维数组的行UINTuCol;//所在雷区二位数组的列UINTuState;//当前状态UINTuAttrib;//方块属性UINTuOldState;//历史状态}MINEWND;//雷方块结构体然后定义雷方块的状态类别和属性类别。1布雷随即获取一个状态为非雷的点,将它的属性标志为雷,重复这样的工作,直到布下足够的雷为止,其流程如图1.4所示。图1.4在CMineWnd类中添加游戏的布雷模块的处理函数,该函数的实现如下。voidCMineWndLayMinesUINTrow,UINTcol{//埋下随机种子srandunsignedtimeNULL;UINTi,j;forUINTindex0;indexuRow,m_pOldMine-uCol;ifm_uGameStateGS_WAIT{m_uBtnStateBUTTON_NORMAL;Invalidate;ReleaseCapture;return;}//假若周围已经标识的雷=周围真正的雷数,拓展ifm_pOldMine-uStateSTATE_FLAG{OpenAroundm_pOldMine-uRow,m_pOldMine-uCol;}ifErrorAroundFlagm_pOldMine-uRow,m_pOldMine-uCol{Deadm_pOldMine-uRow,m_pOldMine-uCol;ReleaseCapture;return;}}else{//如果游戏尚未开始,点击左键启动游戏ifm_uGameStateGS_WAIT{ifm_uTimer{KillTimerID_TIMER_EVENT;m_uTimer0;}m_uSpendTime1;Invalidate;ifm_bSoundful{sndPlaySoundLPCTSTRLockResourcem_pSndClock,SND_MEMORY|SND_ASYNC|SND_NODEFAULT;}//启动定时器m_uTimerSetTimerID_TIMER_EVENT,1000,NULL;//布雷LayMinesm_pOldMine-uRow,m_pOldMine-uCol;//layalltheminesdown//改变游戏状态为运行/GS_RUNm_uGameStateGS_RUN;}ifm_pOldMine-uOldStateSTATE_NORMAL{//当该雷区域为正常未作标记才打开//如果该区域为雷,则死亡ifIsMinem_pOldMine-uRow,m_pOldMine-uCol{Deadm_pOldMine-uRow,m_pOldMine-uCol;ReleaseCapture;return;}//thespecialMINEWNDisnotamine//不是雷的时候,获取其周围的雷数目aroundGetAroundNumm_pOldMine-uRow,m_pOldMine-uCol;//如果为空白区域,拓展,否则打开该区域(显示周围有多少雷数)ifaround0ExpandMinesm_pOldMine-uRow,m_pOldMine-uCol;elseDrawDownNumm_pOldMine,around;}elseifm_pOldMine-uOldStateSTATE_DICEY{//标志为“”问号的时候m_pOldMine-uStateSTATE_DICEY;}//判断是否为胜利ifVictory{Invalidate;ReleaseCapture;return;}}break;caseGS_VICTORYcaseGS_DEADReleaseCapture;//releasethecursorreturn;defaultbreak;}m_uBtnStateBUTTON_NORMAL;Invalidate;}else{//点击非雷区域ifm_uGameStateGS_WAIT||m_uGameStateGS_RUN{m_uBtnStateBUTTON_NORMAL;InvalidateRectrcBtn;}}ReleaseCapture;//releasethecursorCWndOnLButtonUpnFlags,point;}在函数体的开始部分,先用rcBtn和rcMineArea两个矩形变量存储游戏的用户提示区域位置中的笑脸图区域以及雷区域的位置。利用接口函数PtInRect判断当前鼠标的位置(由参数point携带鼠标当前位置信息)是否在这两个区域内,如果检测到鼠标左键点击并释放在笑脸图的按钮区域rcBtn上,则调用初始化函数重新开始游戏,如果检测到鼠标左键点击并释放在雷区域rcMineArea,假若当前游戏状态处于已初始化完成但尚未开始的状态GS_WAIT时,则打开计时器,并且调用LayMines函数进行布雷,然后修改游戏状态为GS_RUN进入游戏。接着判断点击在小方块的状态是否被用于通过右键标记(可以标记为雷或者未知,此时游戏规则规定左键点击不生效),如果未标记,该状态为普通状态STATE_NORMAL时,先通过IsMine检测是否点中地雷而失败地结束游戏,如果是,则调用函数Dead来进行失败后的工作处理,反之对它进行打开显示与拓展操作。先通过GetAroundNum函数获取当前小方块相邻的8个位置的雷数。如果当前小方块相邻区域的雷数为0,则可以向8个方向进行拓展,并显示该方块区域,直到不可拓展为止;如果当前小方块相邻区域的雷数不为0,则显示该方块区域的相邻雷数,用作提供用户对其他位置的信息判断的提示。拓展操作的实现代码如下。voidCMineWndExpandMinesUINTrow,UINTcol{UINTi,j;UINTminRowrow00row-1;UINTmaxRowrow2;UINTminColcol00col-1;UINTmaxColcol2;UINTaroundGetAroundNumrow,col;//显示该区域的方块状态m_pMines[row][col].uState15-around;m_pMines[row][col].uOldState15-around;//“打开”该区域,重绘DrawSpecialMinerow,col;//对周围一个雷都没有的空白区域ifaround0{foriminRow;iuRow,m_pNewMine-uCol;}else{switchm_pNewMine-uState{//普通状态caseSTATE_NORMALm_pNewMine-uStateSTATE_FLAG;m_pNewMine-uOldStateSTATE_FLAG;m_nLeaveNum--;break;//标记状态caseSTATE_FLAGm_pNewMine-uStateSTATE_DICEY;m_pNewMine-uOldStateSTATE_DICEY;m_nLeaveNum;break;//未知状态caseSTATE_DICEYm_pNewMine-uStateSTATE_NORMAL;m_pNewMine-uOldStateSTATE_NORMAL;break;defaultbreak;}}Invalidate;}}CWndOnRButtonDownnFlags,point;}3.3绘图界面的设计3.3.1雷区、笑脸模块的绘制添加三个位图资源如下。ID分别为ID_BTN_COLOR、ID_MINE_COLOR、ID_NUM_COLOR,并分别添加三个位图类型的变量,然后调用LoadBitmapUINTnIDResource函数来实现位图资源与变量的关联。添加函数DrawButton、DrawMineArea、DrawNumber分别实现笑脸按钮、雷区、数字图像计时器数字和剩余雷数数字的绘图。绘制雷区的函数DrawMineArea的实现代码如下。绘制笑脸按钮的函数实现类似。voidCMineWndDrawMineAreaCPaintDCdc{CDCdcMemory;//用作内存设备//源设备dcMemory.CreateCompatibleDC//使得这个设备与dc兼容//dc是目标设备dcMemory.SelectObjectm_bmpMine;//将内存设备与位图资源关联forUINTi0;im_uYNum;i{forUINTj0;jm_uXNum;j{//根据[i][j]区域的雷方块状态拷贝相应的图像到[i][j]雷区的特定区域dc.StretchBltMINEAREA_FRAME_X16*j,MINEAREA_FRAME_Y16*i,16,16,dcMemory,0,16*m_pMines[i][j].uState,16,16,SRCCOPY;}}}3.3.23D效果外壳模块的绘制首先调用FillSolidRect在框架的左部和顶部分别绘制2个小白条,这样看起来有点立体的,然后调用Draw3dRect在笑脸以及计时显示区域周围绘上一个较小的3D边框,最后在雷区周围绘上一个较大的3D边框。3.3.3数字模块的绘制数字图像的绘制不是由鼠标事件触发的,而是由系统时间触发的。首先在CMineWnd类中添加定时器标识的成员变量m_uTimer和一个记录游戏开始直到目前所花费的时间的成员变量m_uSpendTime。接着在游戏的开始函数布下时间种子,时间间隔为1000us,然后选择到预定时间间隔后发送Windows命令消息函数WM_TIMER。接着在CMineWnd类中找到对应的消息WM_TIMER,并为其添加重写函数OnTimer,该函数首先判断这次的WM_TIMER命令是否为所布下的时间种子到时而产生的,如果是则让使用的时间变量m_uSpendTime自增,然后通知系统重绘图像。忽略此处..

注意事项

本文(用VC++设计与实现扫雷系统)为本站会员(星星008)主动上传,沃文网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知沃文网(发送邮件至2622162128@qq.com或直接QQ联系客服),我们立即给予删除!

温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服点击这里,给沃文网发消息,QQ:2622162128 - 联系我们

版权声明:以上文章中所选用的图片及文字来源于网络以及用户投稿,由于未联系到知识产权人或未发现有关知识产权的登记,如有知识产权人并不愿意我们使用,如有侵权请立即联系:2622162128@qq.com ,我们立即下架或删除。

Copyright© 2017-2019 www.wodocx.com ,All Rights Reserved |陕ICP备19002583号  

陕公网安备 61072602000132号     违法和不良信息举报:0916-4228922