用VC++编写扫雷游戏

华中师范大学信息技术系研98(430079) 王洪亚

本文从分析Windows扫雷游戏的功能特点开始,应用面向对象的可视化编程语言Visual C++给出了个功能模块的具体实现方法,并提供了编写小游戏程序的一般方法和Visual C++的一些使用技巧。

首先分析扫雷的最基本功能。

点击鼠标左键于未知区域,如果未知区域有雷,游戏停止,显示所有的地雷。如果没雷,则显示周围雷数,如果周围没雷,则再查看周围八个区域是否有雷直到有雷为止并显示,这其实是一个递归过程。

点击鼠标右键于未知区域,则将其置为有雷而不管是否真的有雷。可选择初、中、高三级并可自定义雷数和区域大小。

雷区上部左侧显示总雷数减被标明有雷区域的数目。

雷区上部中间位置显示一按钮用于开局和显示鼠标动作的结果。

雷区上部右侧显示扫雷的时间。

将雷全部扫清后,则显示一对话框将你的姓名记入排行榜。以时间排序。

为完成上述功能,应用Visual C++的具体技术细节如下:

1. 应用AppWizard创建基于SDI的应用程序CBombApp,去除打印和状态条支持,在资源编辑器中修改菜单和相应的加速键,使其与Windows扫雷游戏一致。具体为开局(ID-GAME-BEGIN)、初级(ID-GAME-JUNIOR)、中级(ID-GAME-MIDDLE)、高级(ID-GAME-SENIOR)、自定义(ID-GAME-CUSTOM)、颜色(ID-GAME-COLOR)、英雄榜(ID-GAME-SORT)、退出(ID-GAME-EXIT)、帮助(ID-HELP)。

2. 在资源编辑器中对应于雷区的每个小区域的13个属性。用画笔或其他绘图工具绘制出相对应的13个10乘10的16色小位图,三个对应于小人表情的20乘20的16色小位图,供更换颜色时使用的一套与前16个对应的单色位图,显示时间和雷数的0~9十个数字位图(底色为黑色)。

定制CUSTOMER对话框,内含三个静态文本控件和三个编辑控件,三个编辑控件分别对应成员m_iRowNum,m_iColumnNum,m_iBombNum。该对话框用于定制雷数,行列数,其相应的MFC类为CCustomer。定制SORT对话框,内含九个静态文本控件,其中六个显示排行榜的姓名和时间,其对应的MFC类为CSort。定制INPUT对话框,内含一个静态文本控件和一个编辑控件,编辑控件用于在游戏成功结束时输入姓名,其对应的MFC类为CInput。

3. 定义类Bomb,封装每颗雷的相关属性。

Class Bomb

{

public:

int isbomb;//决定初始时是否是雷

bool issel; //判断区域是否被处理过且周围有雷

bool isdone;//判断递归时是否被处理过

int num; //周围雷数

bool findbomb; //排雷者认为是雷时置一(但是不一定真是雷)

} ;

4. 重载CMainFrame中PreCreateWindow,并设置相应属性,使其窗体大小固定,这样就固定了显示区域的大小为初始10乘10个雷和外加雷区上部的控制区域,部分代码如下。

cs.style=WS_OVERLAPPED|WS_SYSMENU| WS_BORDER|WS_MINIMIZEBOX;

cs.cy = 10*15+6;

cs.cx = 10*15+60; //6和60分别是横纵的附加值,用于边框、菜单、标题条、控制区域。

5. 游戏的主要工作就是呈现不断变换的图形或动画,并按用户的输入交互进行显示,而Windows文档-----视窗构架中的视窗的功能正是接受用户输入并负责显示,因此由CView类来完成扫雷的大部分工作。在CBombView中定义下列成员变量记录相关操作的结果或对象的状态。

Bomb m_bomb[30][30]; //最大的地雷区域

CString m_CurrentTime; //用于记录并显示扫雷时间

CTime m_BeginTime;//记录游戏开始时的时间

BOOL m_TimerBegin;//定时器是否开启

int m_iBomNum;//雷的数目

int m_iRow;//雷的行数

int m_iColumn;//雷的列数

int m_iBombFound;//指示被认为是雷的数目

CBitmapButton m_bitButton;//控制区的位图按钮

int m_CurrentLevel;//指示当前游戏的级别

BOOL m_bIsColor;//指示当前是彩色还是单色

CBitmap m_bmBomb[12];//用于存放12个小位图

int m_iGameOver;//游戏未结束置0,已清除所有的雷置1,被炸死置2。

重载CBombView中OnCreate函数创建位图按钮,该位图按钮的两幅位图对应了正常、排雷正确两种状态,当要显示被炸死的状态时应动态销毁该按钮,并重新创建一位图对应正常和被炸死两种状态,将该位图按钮的ID号定为ID_GAME_BEGIN,这样一来当点击按钮时便可重新开始游戏,部分代码如下。

CRect rcclient;

GetClientRect(&rcclient);

CRect rect(rcclient.cx/2-8,10,rcclient.cx/2+8,20);

m_Button.Create("New",BS_DEFPUSHBUTTON|WS_VISIBLE|

BS_OWNERDRAW,rect,this,ID_GAME_BEGIN);

m_Button.LoadBitmaps(IDB_FACE1, IDB_FACE2);

显示时间的功能相对比较简单,在响应第一个WM_LBUTTOMDOWN消息时开启定时器,并记录游戏开始的时间,在WM_TIME消息响应函数OnTimer中获得当前时间,减去游戏开始时的时间,在显示时间的客户区域显示得到的时间差(用数字位图),当游戏结束时(排完全部雷或被炸死)关闭定时器,停止显示。

WM_LBUTTOMDOWN消息响应函数OnLButtomDown是处理用户输入的主要执行者,函数首先判断点中位置是否是雷,是则关闭定时器,销毁原位图按钮,创建一对应正常和被炸死两种状态的新位图按钮,并调用SetState将其设置为PUSHDOWN(小人哭的状态),将m_bGameOver,置为TRUE标志游戏结束,否则先调用SetState 设置位图按钮为PUSHDOWN (小人笑的状态),并在OnLButtomUp中设置位图按钮为正常状态,然后调用Caculate函数记下周围雷的数目,最后调用Invalidate使客户区无效,迫使OnDraw函数重绘客户区域,在调用Invalidate时不应重画背景,避免闪烁,这样就完成了在雷区按下左键的响应动作。

WM_RBUTTOMDOWN消息响应函数OnLButtomDown将被认为有雷位置的m_iBombNum.findbomb置一,减少左上角的雷记数,然后判断是否真正全部排完了雷,是则结束游戏弹出INPUT对话框,让扫雷的人输入姓名,在响应IDOK通知码时将其写入注册表,没有全部排完则使客户区无效,迫使OnDraw函数重绘客户区域完成在雷区按下右键的动作。

OnDraw函数在每次点击左键或右键时都会被调用重雷区和控制区域,因为点击情况的复杂性和雷属性的多元化导致OnDraw函数需要精心设计,下面为其流程:图1

函数Caculate计算某个雷周围的雷数,根据前面的分析知道,计算某个雷周围的雷数本身就是一个递归过程,在编制时应注意递归的边界条件,稍不注意会陷入无穷递归而耗尽了系统的资源,下面为其流程:

图2

6. 菜单命令的响应是游戏交互的另一个重要方式,下面的九个命令响应函数分别与九个菜单项相对应,用以完成用户的更新和设置命令。

OnGameBegin完成初始时间清零,随机布雷,依据颜色指示装载12幅小位图,使雷区无效调用OnDraw重绘等工作。其中随机布雷就是多次调用rand(),根据其返回值决定m_bomb[I][j].isbomb的值。

OnGameCustom首先弹出CCustomer对话框,在用户输入设置后响应IDOK通知码时将用户输入的雷数、行列数分别赋给CView的数据成员m_iBombNum、m_iRow、m_iColumn,得到框架窗口的指针,用其调用MoveWindow将窗口调至所需大小,销毁原位置的位图按钮,并在X轴坐标为新窗口宽1/2减8处,Y轴坐标为新窗口顶部加30的位置创建一新按钮。最后调用OnGameBegin重新开始游戏。

OnGameJunior、OnGameMiddle、OnGameSenior三个函数与OnGameCustom类似,只不过将分别赋给CView的数据成员m_iBombNum、m_iRow、m_iColumn以固定的值,其大小可由编程者自定,笔者定为Junior(20,8,8,)、Middle(40,13,13)、Senior(99,20,25)。

OnGameColor函数销毁原位图按钮,根据重新装载位图的标志m_IsColor来创建新的位图按钮,将装载12幅单色位图的标志取反,调用OnGameBegin重新开始游戏。

OnGameSort函数根据当前游戏级别从注册表中读出排名并弹出SORT对话框显示结果。到现在为止,一个自己编制的扫雷游戏就基本完成了,将数百行代码编译一下,找出小错误,最后BUILD一遍,RUN一下,好了,可爱的扫雷游戏就出现在你的面前了。怎么样,自己的劳动成果并不比Microsoft的差吧,而且你还可以把小位图画成各种样子,当然你自己要认得出才行了。

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: VC编写串口通讯软件主要包括如下步骤: 1. 导入相关头文件和库文件:在VC中,首先需要导入串口通讯相关的头文件和库文件,例如#include <windows.h>用于使用串口相关的函数等。 2. 初始化串口参数:该步骤主要是设置并打开串口,确定串口的波特率、数据位、停止位、校验位等参数,以确定通信的稳定性和正确性。 3. 读取串口数据:使用相关的函数来读取串口接收到的数据,一般是通过循环方式进行读取,直到读取到特定的数据帧或者结束符为止。 4. 处理串口数据:对于读取到的串口数据,根据自己的需求进行处理,例如提取某些特定数据的部分,或者进行数据解析和转换等。 5. 发送数据到串口:通过使用相关的函数,将处理过后的数据发送到串口,以实现与外部设备的通信。 6. 关闭串口:在使用完串口后,需要关闭串口,释放相关资源,并进行善后处理。 除了上述的基本步骤,还可以根据具体需求进行一些额外的功能设计,例如加入界面显示模块、错误处理模块、定时发送模块等,以满足用户的更多需求。 总之,使用VC编写串口通讯软件需要了解串口通讯相关的知识,掌握相关的编程技巧,并根据具体需求进行合理的设计和开发。 ### 回答2: VC是指Visual C++,是微软推出的一款集成开发环境,用于开发C和C++程序。编写串口通讯软件可以通过VC来实现。 首先,我们需要在VC中创建一个新的项目。选择Win32控制台应用程序,并设置项目名称和存储路径。 接下来,我们需要添加串口通讯库。VC提供了一些开源的串口库,如Serial Communication Library (SCL),可以从互联网上下载并添加到项目中。 然后,我们需要设置串口参数。可以创建一个新的类或函数来设置串口的波特率、数据位、停止位和校验位等参数。同时,还需要打开串口并检查是否成功打开。 接下来,我们可以实现发送和接收数据的功能。可以创建发送数据的函数和接收数据的函数,并在主程序中调用这些函数。在发送数据的函数中,我们可以将要发送的数据写入串口缓冲区,然后等待数据发送完成。在接收数据的函数中,我们可以从串口缓冲区读取接收到的数据,并进行相应的处理。 最后,我们可以添加用户界面来操作串口通讯软件。可以使用VC提供的图形界面库,如MFC或Windows Forms,来创建一个简单的界面,包括打开/关闭串口、设置串口参数、发送数据和显示接收数据等功能。 当完成编写串口通讯软件后,我们可以进行调试和测试。可以使用调试工具和串口调试工具来验证软件的功能和稳定性。 总之,通过使用VC编写串口通讯软件,我们可以方便地实现串口通讯功能,并应用于各种领域,如嵌入式系统、工业自动化和通信设备等。 ### 回答3: 编写串口通讯软件需要通过vc(Visual C++)编程语言来实现。首先,我们需要设置串口相关的参数,包括波特率、数据位、停止位和校验位等。然后,通过vc编程语言提供的相关函数,打开串口并进行通讯的设置。 在串口通讯软件中,我们需要实现发送和接收数据的功能。发送数据时,我们可以通过vc编程语言提供的函数,将需发送的数据封装成指定格式,并调用相应的串口发送函数发送出去。接收数据时,我们可以使用vc编程语言提供的串口接收函数,通过循环不断接收串口中的数据,并将接收到的数据进行处理和解码。 除了发送和接收数据外,串口通讯软件还应该具备其他功能,比如设置串口参数、打开和关闭串口等。通过vc编程语言提供的相关函数,我们可以添加用户界面和按钮,实现这些功能。用户可以通过点击按钮,选择需要的功能,并在界面上进行相关的设置和操作。 总结起来,编写串口通讯软件需要使用vc编程语言,通过设置串口参数、发送和接收数据等功能实现串口通讯。同时,还可以通过添加用户界面和按钮,提供更多的功能选项和操作方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蝈蝈俊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值