ImageVerifierCode 换一换
格式:DOCX , 页数:29 ,大小:243.90KB ,
资源ID:21472810      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/21472810.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

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

用VC++设计与实现扫雷系统Word文档下载推荐.docx

1、在这个界面中,由众多面积均等的小方块所组成的区域称之为雷区,雷区的大小由用户设置的游戏等级决定。玩家标定未知未知区周围雷数提示玩家标定地雷图1 游戏开始时,系统会在雷区的某些小方块中随机布下若干个地雷。安放好地雷的小方块称之为雷方块,其他的称之为非雷方块。部署完毕后,系统会在其他非雷方块中填充一些数字。某一个具体数字表示与其紧邻的8个方块中有多少雷方块。玩家可以根据这些信息去判断是否可以打开某些方块,并把认为是地雷的方块打上标识。如果某个数字方块周围的地雷全都标记完,可以指向该方块并同时点击鼠标左右键,将其周围剩下的方块挖开。如果编号方块周围地雷没有全部标记,在同时点击鼠标左右键时,其他隐藏或

2、未标记的方块将被按下一次(即闪烁一下)。当玩家将所有地雷找出后,其余的非雷方块区域都已打开,此时游戏结束。在游戏过程中,一旦错误地打开了雷方块则立即失败,游戏结束;当玩家标识的地雷数超过程序设定,虽然打开了全部其余方块,游戏仍然不会结束。在游戏开始后,雷区上方有两个计数器。右边的计数器显示用户扫雷所花费的总时间,以秒为单位;左边的计数器显示当前还剩余多少个雷方块。2.2 功能需求分析游戏需要提供一个菜单栏,上面有不同的相关选项,如游戏的开始、难度设置、退出等。按功能将游戏区域分成两个区域:雷区和提示区。提示区包括两个计数器和一个按键操作结果图像提示。游戏过程中,当玩家用鼠标点击相应的方块,程序

3、就会作出相应的鼠标响应事件,并伴随着GDI绘图,而众多鼠标事件的处理,都是围绕着实现扫雷程序的算法而衍生的。3 总体设计3.1 游戏框架的搭建(1) 工程项目的创建利用应用程序向导创建一个名称为Mine的工程项目。由于不需要诸如工具栏、状态栏等功能,并且扫雷游戏的框架是不允许改变窗口大小的,所以在向导的第四步里面把所有的选项置空,然后点击“Advanced”按钮,在弹出的对话框中选中“Windows Styles”选项卡,将“Maximize box”项置空,其他均使用默认设置。(2) 框架的改造通过类向导添加一个继承于CFrameWnd的类,命名为CMineWnd,删除CMineDoc、CM

4、ineView和CAboutDlg类,将CMineWnd类代替CFrameWnd,让程序启动的时候以此窗口为主窗口予以显示。结果如图2所示。图23.2 菜单的制作参考Windows自带的扫雷游戏,创建出“游戏”和“帮助”菜单,然后通过菜单资源编辑器设定菜单的功能选项,包括难度级别的选择、颜色和音效是否开启、扫雷英雄榜、使用手册、关于软件的信息等。具体的菜单选项如图3所示。 图3(1) 难度级别的选择不同的难度级别有不同的雷区大小和不同的布雷数目,所以通过宏定义预定义不同级别的横向方块数目、纵向方块数目和雷数。并将该宏定义放入新建的头文件“MineDefs.h”中。窗口除了雷区外至少还包括蓝色窗

5、口边缘Frame_wide、白色的视觉效果区line_wide、3D的外壳边框3D_line_wide、雷区mine_area_wide等。于是还需要定义关于位置的宏变量。由于难度级别的不同,窗口大小也会随之改变,因此通过在CMineWnd类增加一个改变窗口大小的函数SizeWindow()去实现。通过ClassWizard分别选择“初级”、“中级”和“高级”菜单资源ID,为它们添加处理函数OnMenuPrimary()、OnMenuSecond() 、OnMenuAdvance()。OnMenuAdvance()的实现如下,另外两个类似。void CMineWnd:OnMenuAdvance

6、() m_uLevel = LEVEL_ADVANCE; m_uXNum = ADVANCE_XNUM; m_uYNum = ADVANCE_YNUM; m_uMineNum = ADVANCE_MINENUM; SetCheckedLevel(); InitGame(); Invalidate(); SizeWindow();(2) 雷区大小的自定义实现首先新建一个自定义雷区对话框资源(IDD_DLG_CUSTOM),然后添加高度、宽度、雷数三个静态文本控件和三个对应的(IDC_HEIGHT)、(IDC_WIDTH) 、(IDC_NUMBER)编辑框控件,最后将OK和Cancel按钮分别改名

7、为“确定”和“取消”。结果如图4。图4接着为该对话框创建CDlgCustom类,然后为三个编辑控件分别添加关联变量m_uHeight、m_uNumber、m_uWidth,最后为OK按钮创建命令消息处理函数OnOK(),代码如下所示。void CDlgCustom:OnOK() UpdateData(); if (m_uWidth 30) m_uWidth = 30; if (m_uHeight 24) m_uHeight = 24; if (m_uNumber m_uWidth * m_uHeight) m_uNumber = m_uWidth * m_uHeight - 1; CMineW

8、nd *pMine = (CMineWnd*)AfxGetMainWnd(); pMine-SetCustom(m_uWidth, m_uHeight, m_uNumber);/ TODO: Add extra validation here CDialog:OnOK();(3) 使用帮助的实现由于Windows 自带有扫雷游戏,所以直接调用它的使用手。为“使用帮助”菜单选项创建命令消息处理函数OnMemuHelpUse(),代码如下所示。显示结果如图5所示。OnMemuHelpUse() /在命令行调用HH.exe,并输入参数NTHelp.CHM,/令其打开该文件,即Windows 自带有扫

9、雷游戏的是使用手册 :WinExec(HH NTHelp.CHM, SW_SHOW);图5(4) 关于信息的实现关于信息的实现代码如下所示。显示结果如图6所示。OnMemuAbout() ShellAbout(this-m_hWnd, 扫雷, yixiaoqianjin,NULL);图6(5) 扫雷英雄榜的实现首先创建两个对话框模板,一个用作当用户胜利结束游戏并打破历史记录后弹出的签名记录对话框模板IDD_DLG_NEWRECORD,另外一个是用以显示以往最高的游戏记录的对话框模板IDD_DLG_HERO。如图7和图8所示。图7图8然后为IDD_DLG_HERO对话框模板创建CDlgHero类

10、,分别为编辑框控件添加关联变量m_szBHolder、m_szBRecord、m_szEHolder、m_szERecord、m_szIHolder、m_szIRecord,并将Cancel按钮的ID和标题分别改为IDC_RESET和重新计分,三个静态文本标题设置为初级记录、中级记录、高级记录,最后为重新计分按钮创建命令消息处理函数OnReset()和其他成员函数。对IDD_DLG_NEWRECORD对话框模板类似处理。3.3布雷,扫雷核心算法的设计与实现(1) 算法的设计把整个雷区看成一个二维数组,aij周围的雷个数是由如下8个雷区决定的(如果超出边界,应该再加以判断):ai-1j-1, a

11、i-1j, ai-1j+1,ai, aij+1,ai+1 j-1, ai+1j, ai+1j+1,在被展开时,检查周围的雷数是否与周围标示出来的雷数相等,如果相等则展开周围未标示的雷区。这样新的雷区展开又触发这个事件,就这样递归下去,一直蔓延到不可展开的雷区。(2) 核心算法的实现整个游戏程序包含3个阶段:布雷、扫雷过程和结果(并不是操作结果展示,而是在扫雷过程中,玩家通过与游戏交互后的操作结果展示)。首先定义雷方块的数据结构,具体描述如下所示。typedef struct UINT uRow; /所在雷区二维数组的行 UINT uCol; /所在雷区二位数组的列 UINT uState; /

12、当前状态 UINT uAttrib; /方块属性 UINT uOldState; /历史状态 MINEWND; / 雷方块结构体然后定义雷方块的状态类别和属性类别。A 布雷随即获取一个状态为非雷的点,将它的属性标志为雷,重复这样的工作,直到布下足够的雷为止,其流程如图9所示。在CMineWnd类中添加游戏的布雷模块的处理函数,该函数的实现如下。LayMines(UINT row, UINT col)/埋下随机种子 srand( (unsigned)time( NULL ) ); UINT i, j; for(UINT index = 0; index uRow, m_pOldMine-uCol

13、); if (m_uGameState = GS_WAIT) m_uBtnState = BUTTON_NORMAL; Invalidate(); ReleaseCapture(); return; /假若周围已经标识的雷周围真正的雷数,拓展 if (m_pOldMine-uState != STATE_FLAG) OpenAround(m_pOldMine- if (ErrorAroundFlag(m_pOldMine-uCol) Dead(m_pOldMine- else /如果游戏尚未开始,点击左键启动游戏 if (m_uGameState = GS_WAIT) if (m_uTimer

14、) KillTimer(ID_TIMER_EVENT); m_uTimer = 0; m_uSpendTime = 1; if (m_bSoundful) sndPlaySound(LPCTSTR)LockResource(m_pSndClock), SND_MEMORY | SND_ASYNC | SND_NODEFAULT); /启动定时器 m_uTimer = SetTimer(ID_TIMER_EVENT, 1000, NULL); /布雷 LayMines(m_pOldMine- /改变游戏状态为运行/GS_RUN m_uGameState = GS_RUN;uOldState =

15、STATE_NORMAL) /当该雷区域为正常未作标记才打开 /如果该区域为雷,则死亡 if (IsMine(m_pOldMine-uCol) Dead(m_pOldMine- ReleaseCapture(); return; /不是雷的时候,获取其周围的雷数目 around = GetAroundNum(m_pOldMine- / 如果为空白区域,拓展,否则打开该区域(显示周围有多少雷数) if (around = 0) ExpandMines(m_pOldMine- else DrawDownNum(m_pOldMine, around); else if (m_pOldMine-uOl

16、dState = STATE_DICEY)/标志为“?”问号的时候 m_pOldMine-uState = STATE_DICEY; /判断是否为胜利 if (Victory() break; case GS_VICTORY: case GS_DEAD: ReleaseCapture(); return; default : m_uBtnState = BUTTON_NORMAL; Invalidate(); else /点击非雷区域 if (m_uGameState = GS_WAIT | m_uGameState = GS_RUN) m_uBtnState = BUTTON_NORMAL;

17、 InvalidateRect(rcBtn); ReleaseCapture(); CWnd:OnLButtonUp(nFlags, point);在函数体的开始部分,先用rcBtn和rcMineArea两个矩形变量存储游戏的用户提示区域位置中的笑脸图区域以及雷区域的位置。利用接口函数PtInRect()判断当前鼠标的位置(由参数point携带鼠标当前位置信息)是否在这两个区域内,如果检测到鼠标左键点击并释放在笑脸图的按钮区域rcBtn上,则调用初始化函数重新开始游戏,如果检测到鼠标左键点击并释放在雷区域rcMineArea,假若当前游戏状态处于已初始化完成但尚未开始的状态GS_WAIT时,则

18、打开计时器,并且调用LayMines()函数进行布雷,然后修改游戏状态为GS_RUN进入游戏。接着判断点击在小方块的状态是否被用于通过右键标记(可以标记为雷或者未知,此时游戏规则规定左键点击不生效),如果未标记,该状态为普通状态STATE_NORMAL时,先通过IsMine()检测是否点中地雷而失败地结束游戏,如果是,则调用函数Dead()来进行失败后的工作处理,反之对它进行打开显示与拓展操作。先通过GetAroundNum()函数获取当前小方块相邻的8个位置的雷数。如果当前小方块相邻区域的雷数为0,则可以向8个方向进行拓展,并显示该方块区域,直到不可拓展为止;如果当前小方块相邻区域的雷数不为

19、0,则显示该方块区域的相邻雷数,用作提供用户对其他位置的信息判断的提示。拓展操作的实现代码如下。ExpandMines(UINT row, UINT col) UINT minRow = (row = 0) ? 0 : row - 1; UINT maxRow = row + 2; UINT minCol = (col = 0) ? col - 1; UINT maxCol = col + 2; UINT around = GetAroundNum(row, col); /显示该区域的方块状态 m_pMinesrowcol.uState = 15 - around; m_pMinesrowco

20、l.uOldState = 15 - around; / “打开”该区域,重绘 DrawSpecialMine(row, col); /对周围一个雷都没有的空白区域 if (around = 0) for (i = minRow; i maxRow; i+) for (j = minCol; j maxCol; j+) /对于周围可以拓展的区域进行的规拓展 if (!(i = row & j = col) & m_pMinesij.uState = STATE_NORMAL & m_pMinesij.uAttrib ! if (!IsInMineArea(i, j) continue; ExpandMines(i, j); / 递归拓展操作经过打开或拓展后,最后通过Victory()判断游戏是否已经胜利结束,如果是则作胜利处理。鼠标右击事件其流程如图12所示。

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

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