软件综合设计项目报告书(扫雷)_第1页
软件综合设计项目报告书(扫雷)_第2页
软件综合设计项目报告书(扫雷)_第3页
软件综合设计项目报告书(扫雷)_第4页
软件综合设计项目报告书(扫雷)_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、课程:软件综合设计项目 组员:刘梦曦、刘敬亚 学号:2010101012、2010101026 班级:通信101软件综合设计项目课程设计报告项目题目 基于C+的扫雷程序设计 组 员 学 号 专业班级 指导老师 报告日期 2013年6月6日 目 录摘 要3一、 需求分析3二、 概要设计3三、 详细设计43.1 游戏系统资源53.1.1菜单资源53.1.2位图资源53.1.3声音资源63.2.1初始化游戏变量83.2.2初始化游戏103.2.3绘制游戏界面113.3游戏功能控制及使用说明的实现143.3.1游戏菜单选项的功能实现143.3.2帮助菜单选项的功能实现163.3.3菜单选项的选中状态控

2、制函数163.4游戏与用户的交互183.4.1鼠标单击事件的处理183.4.2鼠标左键抬起事件的处理193.4.3鼠标左右键同时按下事件的处理223.4.4鼠标左右键同时按下后鼠标抬起事件的处理233.4.5鼠标右键按下事件的处理243.4.6鼠标右键抬起事件的处理253.5游戏结果处理函数26四、 测试与总结284.1软件的测试284.2心得与总结29 摘 要游戏业发展一日千里,该行业极大的影响和改变了人们的生活和娱乐方式,游戏为消费者提供丰富多彩的虚拟空间,使消费者可以自由自在的享受虚拟世界的乐趣,实现自己在现实生活着那个可能永远不能实现的梦想,满足了消费者的心理和精神需求。扫雷游戏是Wi

3、ndows操作系统自带的一个小游戏,过去的几年里Windows操作系统历经数次换代,变得越来越庞大、复杂,但这个可爱的小游戏在任何版本的Windows操作系统里去却依然保持着原貌。但几乎每个电脑使用者都接触过它,并且深爱着这款小游戏。扫雷游戏是比较经典的一款小游戏,实现它的方法很多,可以用很多不同算法和语言实现,如C,C+,VB,JAVA等。该设计以Visual C+ 6.0为开发环境,设计并开发一款扫雷游戏,其功能类似于Windows操作系统自带的扫雷游戏。该报告首先介绍了制作游戏的整体思路及整个游戏设计的流程规划,然后介绍了雷区的布置及地雷随机产生的实现方法;重点介绍了在游戏过程中各事件的

4、处理,其中又以鼠标事件和清除未靠近地雷区方块这两方面最为最要,鼠标事件是利用鼠标所发出的信息了解使用者的意图,进而做出相对应的动作。关键字:扫雷,Visual C+ 6.0,事件1、 需求分析扫雷游戏的基本功能:点击鼠标左键于未知区域,如果未知区域有雷,游戏停止,显示所有的地雷。如果没雷,则显示周围雷数,如果周围没雷,则再查看周围八个区域是否有雷直到有雷为止并显示,这其实是一个递归过程。 点击鼠标右键于未知区域,则将其置为有雷而不管是否真的有雷。可选择初、中、高三级并可自定义雷数和区域大小。雷区上部左侧显示总雷数减被标明有雷区域的数目。雷区上部中间位置显示一按钮用于开局和显示鼠标动作的结果。雷

5、区上部右侧显示扫雷的时间。将雷全部扫清后,则显示一对话框将你的姓名记入排行榜。2、 概要设计本设计实现类似于Windows操作系统自带的扫雷游戏。在设计中,系统开发平台为Windows XP,程序设计语言采用Visual C+,程序运行平台为Windows 2000/XP。在程序设计中,把整个雷区看成一个二维数组,把雷方块定义为具有所在雷区二维数组的行和列、当前状态、方块属性、历史状态的结构体。整个游戏程序包括了布雷、扫雷过程和结果三个阶段,在处理鼠标响应事件中伴随着GDI绘图。程序通过调试运行,实现了设计目标,能够同时满足扫雷游戏初学者和高手的需要。流程规划大致

6、上可以分为三个部分,分别为:画面初始、游戏者按下第一个方块和为非地雷方块时展开。画面初始时,以游戏者最后一次设定的地雷区大小为范围画出地雷区,但此时并未产生地雷。当游戏者按下第一个方块时产生地雷资料并启动定时器,为何在游戏者按下第一个方块才产生地雷资料呢?其主要的用意在于不要让游戏者第一次就踩到地雷,这样在某种程度上可以提高游戏者游玩的气氛。接着就是如何判断按下的方块是非地雷时的处理,这也是整个游戏的技术核心,我们可以通过递归的观念来检查周边的方块是否含有地雷及是否继续往外翻开。 基于以上思路,绘制功能图如下: 扫雷游戏主界面级别选择开局帮助重新开始游戏菜单声音标记英雄榜颜色退出关于扫雷图1.

7、1 扫雷游戏总体功能图开始开局退出选择级别标记声音英雄榜展示相应的效果按钮菜单定义并初始化按钮、菜单等事件处理方块重新开始是否点中雷结束图1.2 总体流程图3、 详细设计扫雷游戏的开发主要包括两大部分:一个部分是布雷,该部分主要将雷随机布置在游戏区域内,以避免出现相同的雷区布置地图。另一部分是扫雷,该部分包括判断鼠标左键点击某区域该区域是否是雷,如果是雷该如何操作,如果不是雷该如何操作,鼠标右键点击某区域时如果判断该区域是雷则加以标记,如果不是雷也加以标记,以及当鼠标双击某区域时,判断与该区域相邻的其它8个区域是否是雷并做一个标记。3.1 游戏系统资源扫雷游戏中用到了很多资源,比如菜单资源、位

8、图资源、声音资源等。3.1.1菜单资源菜单资源主要用于游戏的控制及说明。菜单资源只有两个菜单选项:第1个菜单选项包括游戏控制的选项,第2个菜单选项包含游戏说明的选项,在资源视图中插入这两个菜单选项,如图所示。这些菜单选项的功能将在游戏的主窗体对话框中实现。 图2:游戏菜单选项图3:帮助菜单选项3.1.2位图资源在该项目中,位图资源比较多,也正是这些丰富的位图资源才实现了扫雷丰富的功能,下面按功能介绍各个位图的资源。(1) 游戏状态按钮位图。由于游戏可以处于彩色及黑白两色两种状态,因此也需要载入两种不同的状态按钮的位图资源,如图所示。 图4:彩色状态按钮位图图5:黑白色状态按钮位图资源中的位图自

9、上而下一次对应游戏的正常、胜利、失败、及方块的展开状态。在游戏菜单中选择游戏的颜色状态。(2) 方块状态位图。在主游戏区中每个方块都可能对应很多不同的状态,如初始状态、下压状态、数字状态、雷状态、炸雷状态、标识累状态、错误标志类状态、及位图状态。因此方块状态位图设计如图所示。 图6:方块彩色位图图7:方块黑白色位图(3) 数字位图。在游戏中需要提示累得剩余数量及用户游戏已用的时间。为了美观,将数字设计成8段数码管的方式来显示,设计了两个数字位图,如图所示。 图8:彩色数字位图图9:黑白色数字位图3.1.3声音资源为了是游戏更有趣,该设计还为游戏添加声音资源,并根据游戏的不同状态播放这些资源,如

10、图所示。图10:声音资源当游戏开始后,开始计时,IDR_WAVE_CLOCK对应的声音资源将被播放,每个一秒钟播放一次,与时钟显示同步。当游戏失败时,将播放IDR_WAVE_DEAD对应的声音资源。当游戏胜利是将播放IDR_WAVE_VICTORY对应的声音资源。3.2游戏初始化及游戏界面绘制与游戏的功能相对应,所有的功能都对应这一个实现体。如:等级选择的功能对应着等级选择的实现、游戏交互的功能对应着游戏交互的实现。游戏主要的功能基本都在主游戏窗体类实现。该设计主游戏模块中实现的游戏界面的绘制、游戏初始化、用户交互、绘制游戏界面并初始化游戏。但无论是何种操作,在进行游戏之前都需要初始化游戏数据

11、、绘制游戏界面并初始化游戏,这是实现游戏的第一步。以下为游戏的数据说明。MINEWND* GetMine(long x, long y);protected :UINTm_uXNum;/ X方向小方块个数UINTm_uYNum;/ Y方向小方块个数UINTm_uMineNum;/ 总的雷个数int m_nLeaveNum;/ 剩余的雷个数UINTm_uSpendTime;/ 游戏开始击到目前所花费的时间UINTm_uGameState;/ 游戏状态UINTm_uTimer;/ 定时器标识UINTm_uNewState;/ 当前选中的小方块的状态UINTm_uLevel;/ 当前游戏等级UINT

12、m_uPrimary;/ 初级记录UINTm_uSecond;/ 中级记录UINTm_uAdvance;/ 高级记录CStringm_szPrimary;/ 初级记录保持者CStringm_szSecond;/ 中级记录保持者CStringm_szAdvance;/ 高级记录保持者BOOLm_bLRBtnDown;/ 是否为左右键同时按下BOOLm_bClickBtn;/ 左键按下的时候鼠标是否位于按钮区域内BOOLm_bMarkful;/ 是否能显示标记BOOLm_bColorful;/ 是否彩色显示BOOLm_bSoundful;/ 是否有声音CMenu*m_pSubMenu;/ 子菜单C

13、Bitmapm_bmpMine;/ 雷区背景图像CBitmapm_bmpNumber;/ 数字背景图像CBitmapm_bmpButton;/ 笑脸按钮背景图像CBrushm_brsBG;/ 背景画刷对象COLORREFm_clrDark;/ 各按钮的深色调RECTm_rcClient;/ 客户区域UINTm_uBtnRect3;/ 按钮框区域坐标数组UINTm_uBtnState;/ 按钮状态UINTm_uNumRect3;/ 数字框区域坐标数组(包括时间和雷个数)UINTm_uShellRcX2;/ 内框以及边界的坐标X方向UINTm_uShellRcY2;/ 内框以及边界的坐标Y方向MI

14、NEWNDm_pMines100100;/ 表示雷区内的所有小方块的二维数组MINEWND*m_pNewMine;/ 当前选中的小方块MINEWND*m_pOldMine;/ 上次选中的小方块void*m_pSndDead;/ 失败提示音void*m_pSndVictory;/ 胜利提示音void*m_pSndClock;/ 时钟提示音;这些定义在主游戏窗体类头文件中的所有变量可以分为8组,子变量声明的顺序是:第1组用来声明表示主游戏区(方块)及累得信息;第2组是画刷、按钮位图、数字位图及方块状态位图,都是用于绘制界面的元素;第3组用于保存主游戏区、时间框、雷数框及笑脸按钮的坐标;第4组用于记

15、录各种游戏状态;第5组用于标识当前游戏特效属性;第6组用于记录英雄榜数据;第7组是各种声音资源的指针;第8组只有一个变量用于保存菜单选项的指针。3.2.1初始化游戏变量LoadWaveSrc()函数用于载入声音资源,实现如下:void CMineWnd:LoadWaveSrc() / 载入声音资源 P397 由OnMemuSound()函数调用HMODULE hMdl;hMdl = AfxGetResourceHandle();HRSRC hSrc;hSrc = FindResource(hMdl, MAKEINTRESOURCE(IDR_WAVE_DEAD), _T("WAVE&q

16、uot;);m_pSndDead = LoadResource(hMdl, hSrc);hSrc = FindResource(hMdl, MAKEINTRESOURCE(IDR_WAVE_VICTORY), _T("WAVE");m_pSndVictory = LoadResource(hMdl, hSrc);hSrc = FindResource(hMdl, MAKEINTRESOURCE(IDR_WAVE_CLOCK), _T("WAVE");m_pSndClock = LoadResource(hMdl, hSrc);··&#

17、183;·与LoadWaveSrc()函数对应的还有FreeWaveSrc()函数,它实现了释放声音资源的功能,实现方法如下:void CMineWnd:FreeWaveSrc() / 释放声音资源 由OnMemuSound()函数调用if (m_pSndDead)FreeResource(m_pSndDead);m_pSndDead = NULL;if (m_pSndVictory) FreeResource(m_pSndVictory);m_pSndVictory = NULL;if (m_pSndClock)FreeResource(m_pSndClock);m_pSndClo

18、ck = NULL;····SizeWindow()函数用来初始化窗体中重要部分的位置,实现如下:void CMineWnd:SizeWindow( void ) /调整窗体,用来初始化窗体中重要部分的位置 UINT uWidth = DEFAULT_FRAME_X + m_uXNum * MINE_WIDTH +LINE_WIDTH_0 * 3 + SIDE_WIDTH_0 + SIDE_WIDTH_1; UINT uHeight = DEFAULT_FRAME_Y + m_uYNum * MINE_HEIGHT + LINE_WIDTH_0 * 3

19、+ SIDE_WIDTH_0 * 2 + SIDE_WIDTH_1 + SHELL_S_H;SetWindowPos(&wndTopMost, 0, 0, uWidth, uHeight, SWP_NOZORDER | SWP_NOMOVE | SWP_NOCOPYBITS);GetClientRect(&m_rcClient);m_uBtnRect0 = m_rcClient.right / 2 - 12;m_uBtnRect1 = m_rcClient.right / 2 - 13;m_uBtnRect2 = m_rcClient.right / 2 + 12;m_uNum

20、Rect0 = m_rcClient.right - 55;m_uNumRect1 = m_rcClient.right - 15;m_uNumRect2 = m_rcClient.right - 54;m_uShellRcX0 = m_rcClient.right;m_uShellRcX1 = m_rcClient.right - 14;m_uShellRcY0 = m_rcClient.bottom;m_uShellRcY1 = m_rcClient.bottom - SHELL_L_START_Y - 5;····最后还要重载窗体的菜单初始化函数,

21、根据上面初始化的数据,设置菜单选项的选中状态,实现如下:void CMineWnd:OnInitMenu(CMenu* pMenu) /菜单初始化函数 CWnd:OnInitMenu(pMenu);if (m_pSubMenu = pMenu->GetSubMenu(0) = 0) AfxMessageBox("初始化菜单失败!");PostQuitMessage(0);elseSetCheckedLevel();/设置等级菜单选项的选中状态SetCheckedMark();SetCheckedColor();/设置颜色菜单选项的选中状态SetCheckedSound

22、();/设置声音菜单选项的选中状态/SetCheckedCheat();3.2.2初始化游戏在窗体的初始化函数中调用了InitGame()函数,该函数用于初始化游戏,实现如下:void CMineWnd:InitGame() / 游戏的初始化 LoadBitmap(); /载入位图资源m_nLeaveNum = m_uMineNum;/剩余雷数m_uSpendTime = 0;/花费的时间m_uBtnState = BUTTON_NORMAL;/状态按钮初始化为正常态m_uGameState = GS_WAIT;/游戏状态为等待状态if (m_uTimer) /定时器已打开KillTimer(

23、ID_TIMER_EVENT);/关闭定时器m_uTimer = 0;/初始化时间m_pNewMine = NULL;/新单击的方块m_pOldMine = NULL;/上次单击的方块FreeMines();/将所有的方块初始化为原始状态for (UINT i = 0; i<m_uYNum; i+) for (UINT j = 0; j<m_uXNum; j+)m_pMinesij.uRow = i;m_pMinesij.uCol = j;m_pMinesij.uState = STATE_NORMAL;/正常态m_pMinesij.uAttrib = ATTRIB_EMPTY;m

24、_pMinesij.uOldState = STATE_NORMAL;····LoadBitma()函数根据当前颜色状态为游戏载入不同的位图资源,实现如下:void CMineWnd:LoadBitmap()if (m_bColorful)/彩色位图模式m_clrDark = COLOR_DARK_GRAY;/灰色m_bmpMine.DeleteObject();m_bmpMine.LoadBitmap(IDB_MINE_COLOR);/载入方块的彩色状态位图m_bmpNumber.DeleteObject();m_bmpNumber.LoadBitma

25、p(IDB_NUM_COLOR);/载入数字的彩色位图m_bmpButton.DeleteObject();m_bmpButton.LoadBitmap(IDB_BTN_COLOR);/载入状态按钮的彩色位图else /黑白色模式m_clrDark = COLOR_BLACK;m_bmpMine.DeleteObject();m_bmpMine.LoadBitmap(IDB_MINE_GRAY);/载入方块的黑白色状态位图m_bmpNumber.DeleteObject();m_bmpNumber.LoadBitmap(IDB_NUM_GRAY);/载入数字的黑白色位图m_bmpButton.

26、DeleteObject();m_bmpButton.LoadBitmap(IDB_BTN_GRAY);/载入状态按钮的黑白色位图3.2.3绘制游戏界面主窗体的OnPaint()函数实现绘制游戏界面的功能,利用双环冲的绘图方法实现实现界面闪屏的效果。依次绘制状态按钮、雷数标识、时间记录、游戏边框及主游戏区,实现如下:void CMineWnd:OnPaint() /实现绘制游戏界面的功能 CPaintDC dc(this); / 用以屏幕显示的设备CDC dcMemory; / 内存设备CBitmap bitmap;if (!dc.IsPrinting() if (dcMemory.Creat

27、eCompatibleDC(&dc)/ 与dc设备兼容/ 使得bitmap与实际显示的设备兼容if (bitmap.CreateCompatibleBitmap(&dc,m_rcClient.right,m_rcClient.bottom)/ 内存设备选择物件位图dcMemory.SelectObject(&bitmap);/绘制背景框dcMemory.FillRect(&m_rcClient, &m_brsBG);DrawButton(CPaintDC&) dcMemory);/笑脸按钮绘图DrawNumber(CPaintDC&) d

28、cMemory);/文字绘图(计时器文字和剩余雷数文字)DrawShell(CPaintDC&) dcMemory);/3D效果外壳绘图DrawMineArea(CPaintDC&) dcMemory);/雷区绘图/ 将内存设备的内容拷贝到实际屏幕显示的设备dc.BitBlt(m_rcClient.left, m_rcClient.top, m_rcClient.right, m_rcClient.bottom, &dcMemory, 0, 0, SRCCOPY);bitmap.DeleteObject(); /释放位图内存····

29、;DrawButton()函数实现了绘制状态按钮的功能。其实状态按钮并不是真正按钮,它只是一个绘有表情及3D边框的一片区域,该片区域根据当前的游戏状态代表按钮上的表情,实现如下:void CMineWnd:DrawButton(CPaintDC &dc)CDC cdc; /内存设备cdc.CreateCompatibleDC(&dc); /设备兼容性cdc.SelectObject(m_bmpButton);/载入状态按钮位图dc.StretchBlt(m_uBtnRect0, 16, 24, 24, &cdc, 0, 24 * m_uBtnState, 24, 24,

30、 SRCCOPY); /绘制状态按钮上的位图/ 由于每个标识状态的位图高度是24,因此可以根据m_uBtnState来计算开始当前状态对应位图的高度dc.Draw3dRect(m_uBtnRect1, 15, 26, 26, m_clrDark, m_clrDark); /绘制3D边框实现按钮的效果····DrawNumber()函数实现绘制游戏当前剩余雷数,以及当前游戏时间的功能,它所绘制的雷数及时间随着游戏的进行不断地变化着,实现如下:void CMineWnd:DrawNumber(CPaintDC &dc)CDC dcMemory;/内存

31、设备dcMemory.CreateCompatibleDC(&dc);/创建设备兼容性dcMemory.SelectObject(m_bmpNumber);/载入数字位图dc.Draw3dRect(16, 15, 41, 25, m_clrDark, COLOR_WHITE); /绘制剩余雷数的3D边框dc.Draw3dRect(m_uNumRect0, 15, 41, 25, m_clrDark, COLOR_WHITE); /绘制游戏时间显示区域的3D边框int num;/ 绘制剩余雷数num = (m_nLeaveNum<0) ? 11 : m_nLeaveNum/100;

32、dc.StretchBlt(17, 16, 13, 23, &dcMemory, 0, 276-23*(num+1), 13, 23, SRCCOPY);num = (m_nLeaveNum < 0) ? -(m_nLeaveNum-num*100)/10 : (m_nLeaveNum-num*100)/10;dc.StretchBlt(30, 16, 13, 23, &dcMemory, 0, 276-23*(num+1), 13, 23, SRCCOPY);num = (m_nLeaveNum<0) ? -m_nLeaveNum%10 : m_nLeaveNum

33、%10;dc.StretchBlt(43, 16, 13, 23, &dcMemory, 0, 276-23*(num+1), 13, 23, SRCCOPY);/ 绘制游戏时间num = m_uSpendTime / 100;dc.StretchBlt(m_uNumRect0, 16, 13, 23, &dcMemory, 0, 276-23*(num+1), 13, 23, SRCCOPY);num = (m_uSpendTime-num*100)/10;dc.StretchBlt(m_uNumRect0 + 13, 16, 13, 23, &dcMemory, 0

34、, 276-23*(num+1), 13, 23, SRCCOPY);num = m_uSpendTime%10;dc.StretchBlt(m_uNumRect0+26, 16, 13, 23, &dcMemory, 0, 276-23*(num+1), 13, 23, SRCCOPY);DrawShell()函数实现绘制游戏区域3D边框的功能,它为主窗体绘制了大小两个3D边框(小3D区域用于显示剩余雷数、状态按钮及游戏时间。大3D区域为主游戏区域),实现如下:void CMineWnd:DrawShell(CPaintDC &dc)/ 绘画2条白条dc.FillSolidR

35、ect(0, 0, m_uShellRcX0, LINE_WIDTH_0, COLOR_WHITE);/横向dc.FillSolidRect(0, 0, LINE_WIDTH_0, m_uShellRcY0, COLOR_WHITE);/竖向/ 画小的外壳dc.Draw3dRect(SHELL_S_START_X, SHELL_S_START_Y, m_uShellRcX1, SHELL_S_H, m_clrDark, COLOR_WHITE); / 外侧dc.Draw3dRect(SHELL_S_START_X + 1, SHELL_S_START_Y + 1, m_uShellRcX1 -

36、 2, SHELL_S_H - 2, m_clrDark, COLOR_WHITE); /内侧/ 画大的外壳dc.Draw3dRect(SHELL_L_START_X, SHELL_L_START_Y,m_uShellRcX1, m_uShellRcY1, m_clrDark, COLOR_WHITE); /最外侧dc.Draw3dRect(SHELL_L_START_X + 1, SHELL_L_START_Y + 1,m_uShellRcX1 - 2, m_uShellRcY1 - 2, m_clrDark, COLOR_WHITE); /中间dc.Draw3dRect(SHELL_L_S

37、TART_X + 2, SHELL_L_START_Y + 2, m_uShellRcX1 - 4, m_uShellRcY1 - 4, m_clrDark, COLOR_WHITE); / 最内侧····DrawMineArea()函数实现绘制主游戏区的功能,它根据区域中各个方块的属性来绘制这些方块,实现如下:void CMineWnd:DrawMineArea(CPaintDC &dc)CDC dcMemory; /用作内存设备dcMemory.CreateCompatibleDC(&dc); /使得这个设备与dc兼容dcMemory

38、.SelectObject(m_bmpMine); /将内存设备与位图资源关联for (UINT i = 0; i<m_uYNum; i+) for (UINT j = 0; j<m_uXNum; j+) /根据ij区域的雷方块状态拷贝相应的图像到ij雷区的特定区域dc.StretchBlt(MINEAREA_FRAME_X+16*j, MINEAREA_FRAME_Y+16*i, 16, 16, &dcMemory, 0, 16*m_pMinesij.uState, 16, 16, SRCCOPY);····3.3游戏功能控制及使用

39、说明的实现在游戏菜单中,用户可以选择游戏等级、控制游戏色彩、声音特效,还能查看游戏帮助及游戏说明。3.3.1游戏菜单选项的功能实现游戏菜单选项的子菜单分为5种选项,分别是开局、等级控制、特效控制、英雄榜及退出控制。1、 开局子菜单开局子菜单用于初始化游戏,游戏的等级、特性都没有变化,只是计时清零后初始化游戏。实现如下:void CMineWnd:OnMemuStart() InitGame(); / 游戏初始化Invalidate(); /重绘界面2、 等级控制菜单等级控制菜单选项,除了自定义需要弹出一个用户自定义窗体外,其他3个选项的实现基本相同。void CMineWnd:OnMemuPr

40、imary() /初级游戏 m_uLevel = LEVEL_PRIMARY; /游戏等级控制m_uXNum = PRIMARY_XNUM; /横向方块数m_uYNum = PRIMARY_YNUM; /纵向方块数m_uMineNum = PRIMARY_MINENUM; /雷数/进行游戏初始化操作SetCheckedLevel(); /游戏等级控制菜单属性修改InitGame(); / 初始化游戏Invalidate(); / 重绘界面SizeWindow(); /调整窗体大小void CMineWnd:OnMemuSecond() /中级游戏m_uLevel = LEVEL_SECONDR

41、Y;m_uXNum = SECONDRY_XNUM;m_uYNum = SECONDRY_YNUM;m_uMineNum = SECONDRY_MINENUM;SetCheckedLevel();InitGame();Invalidate();SizeWindow();void CMineWnd:OnMemuAdvance() /高级游戏m_uLevel = LEVEL_ADVANCE;m_uXNum = ADVANCE_XNUM;m_uYNum = ADVANCE_YNUM;m_uMineNum = ADVANCE_MINENUM;SetCheckedLevel();InitGame();I

42、nvalidate();SizeWindow();用户自定义选项的实现基本也类似,只有这些参数需要用户自己输入,因此需要添加一个用户自定义游戏模块,它主要为用户提供了输入行数、雷数及雷数的功能,界面设计如图所示。此外还需要利用向导为窗体类添加控件的关联变量,如图所示。 图11:用户自定义游戏界面图12:为用户自定义模块添加控件关联变量其中,m_uNumber为保存雷数、m_uWidth为保存列数、m_uHeight为保存函数。此外还要为窗体类添加两个函数,用于设置及获取这3个变量的值:void GetData(UINT *q,UINT *r,UINT *n);Void SetData(UINT

43、 q,UINT r,UINT n);SetCustom()函数用户获取这3个值,而SetCustom()函数用户设置这3个值,实现如下:void CMineWnd:SetCustom(UINT xNum, UINT yNum, UINT mNum) / 用户自定义设置 m_uXNum = xNum;/行数m_uYNum = yNum;/列数m_uMineNum = mNum;/雷数void CDlgCustom:InitData(UINT xNum, UINT yNum, UINT mNum)/获取用户设置的值 由OnMemuCustom调用(在CMineWnd里面)m_uWidth = xN

44、um;/行数m_uHeight = yNum;/列数m_uNumber = mNum;/雷数3、 游戏特效菜单游戏特效菜单选项,可以控制游戏的彩色、声音。实现如下:void CMineWnd:OnMemuColor() /颜色控制 m_bColorful = !m_bColorful; / 颜色标识 将颜色标识取反LoadBitmap(); /重新载入位图SetCheckedColor(); /设置颜色按钮的选中状态Invalidate(); / 重绘界面void CMineWnd:OnMemuSound() /声音控制 m_bSoundful = !m_bSoundful;/声音标识 将声音

45、标识取反SetCheckedSound(); /设置声音选项的选中状态if (m_bSoundful) /根据情况释放或载入声音资源LoadWaveSrc(); /载入资源elseFreeWaveSrc(); /释放资源4、 退出菜单退出菜单选项是当用户选择这个菜单选项时,无论游戏处于什么状态都将直接结束游戏并退出程序。Void CMineGameDlg:OnExit()PostQuitMessage(0);3.3.2帮助菜单选项的功能实现帮助菜单只有两个子菜单:一个是联机帮助;一个是游戏版本的说明。实现如下:void CMineWnd:OnMemuHelpUse() /帮助打开文档 :Win

46、Exec("HHNTHelp.CHM", SW_SHOW);void CMineWnd:OnMemuAbout() /显示游戏说明ShellAbout(this->m_hWnd,"扫雷", "skybluehacker",NULL);/显示关于窗体3.3.3菜单选项的选中状态控制函数等级与特效控制菜单选项都有选中状态控制函数,以提示当前游戏的等级及特效应用情况,实现如下:void CMineWnd:SetCheckedLevel() /设置游戏级别 由OnMemuCustom()函数调用 if (m_pSubMenu)/将等级菜

47、单选项处于非选中状态m_pSubMenu->CheckMenuItem(IDM_PRIMARY, MF_UNCHECKED | MF_BYCOMMAND);/CheckMenuItem是实现选中状态的关键P410m_pSubMenu->CheckMenuItem(IDM_SECOND, MF_UNCHECKED | MF_BYCOMMAND);m_pSubMenu->CheckMenuItem(IDM_ADVANCE, MF_UNCHECKED | MF_BYCOMMAND);m_pSubMenu->CheckMenuItem(IDM_CUSTOM, MF_UNCHEC

48、KED | MF_BYCOMMAND);switch(m_uLevel)/根据当前游戏等级将相应的等级处于选中状态case LEVEL_PRIMARY:m_pSubMenu->CheckMenuItem(IDM_PRIMARY, MF_CHECKED | MF_BYCOMMAND);break;case LEVEL_SECONDRY:m_pSubMenu->CheckMenuItem(IDM_SECOND, MF_CHECKED | MF_BYCOMMAND);break;case LEVEL_ADVANCE:m_pSubMenu->CheckMenuItem(IDM_ADV

49、ANCE, MF_CHECKED | MF_BYCOMMAND);break;case LEVEL_CUSTOM:m_pSubMenu->CheckMenuItem(IDM_CUSTOM, MF_CHECKED | MF_BYCOMMAND);break;default: break;void CMineWnd:SetCheckedColor()/颜色菜单选项 由OnMemuColor()函数调用if (m_pSubMenu)if (m_bColorful) /处于选中状态m_pSubMenu->CheckMenuItem(IDM_COLOR, MF_CHECKED | MF_BY

50、COMMAND);else /处于非选中状态m_pSubMenu->CheckMenuItem(IDM_COLOR, MF_UNCHECKED | MF_BYCOMMAND);void CMineWnd:SetCheckedSound()/声音菜单选项 由OnMemuSound()函数调用if (m_pSubMenu)if (m_bSoundful) /处于选中状态m_pSubMenu->CheckMenuItem(IDM_SOUND, MF_CHECKED | MF_BYCOMMAND);else /处于非选中状态 m_pSubMenu->CheckMenuItem(IDM

51、_SOUND, MF_UNCHECKED | MF_BYCOMMAND);····在这里,CheckMenuItem()函数是实现选中状态控制的关键,函数原型如下:DWORD CheckMenuItem(UINT uIDCheckItem,UINT uCheck);3.4游戏与用户的交互游戏需要相应用户的动作及实现用户的游戏过程。在扫雷游戏中,用户主要有鼠标单击、鼠标右击、及左右键同时单击等动作。根据用户不同的动作及动作的不同位置,游戏相应作出相应的响应。3.4.1鼠标单击事件的处理游戏中,鼠标单击是用户最多的游戏动作,可单击状态按钮开始游戏,也可单击主

52、游戏区展开用户认定的非雷方块。实现如下:void CMineWnd:OnLButtonDown(UINT nFlags, CPoint point) /鼠标单击事件的处理/按钮所在的区域CRect rcBtn(m_uBtnRect1, 15, m_uBtnRect2, 39);/雷区所在的区域CRect rcMineArea(MINE_AREA_LEFT, MINE_AREA_TOP, MINE_AREA_LEFT + m_uXNum * MINE_WIDTH, MINE_AREA_TOP + m_uYNum * MINE_HEIGHT);SetCapture();/ capture the m

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论