扫雷游戏制作过程(CSharp 描述):第八节、整体完善

这一节我们将介绍结束游戏的方法,以及一些整体方面的完善。首先考虑失败的情况,它会将所有的地雷都显示出来。我们新建一个 GameLost 函数: private void GameLost() { for(int i = 1; i<= nWidth; i++) { for(int j = 1; j<= nHeight; j++) { if(pMine[i, j] == -1 && (pState[i, j] == 0 || pState[i, j] == 3)) // 未点开或者标记为问号的雷 { pState[i, j] = 1; // 点开该地雷 } } } } 在游戏结束的地方调用 GameLost 函数,因为我们上一节中讲述的游戏结束都是失败的情况: if(nFlagCnt == nSysCnt || nFlagCnt + nDoubtCnt == nSysCnt) // 打开九宫格 { bool bFlag = OpenMine(MouseFocus.X, MouseFocus.Y); if(!bFlag) // 周围有地雷 { // 结束游戏 GameLost(); } } if(pMine[MouseFocus.X, MouseFocus.Y] != -1 && pState[MouseFocus.X, MouseFocus.Y] == 0) { dfs(MouseFocus.X, MouseFocus.Y); } else { // 地雷,游戏结束 GameLost(); } 我们发现游戏结束的时候,虽然所有的格子都打开了,但是并...

2015年5月2日 · 5 分钟 · 2300 字 · Kai Wang

扫雷游戏制作过程(CSharp 描述):第七节、内部实现(续)

这一节我们主要讲解扫雷时鼠标单击的事件。我们首先介绍左键单击的事件,分为两种情况——遇到地雷,游戏结束;不是地雷,自动点开相邻的非地雷区域,并且显示对应地雷区域周围地雷的数目。 我们首先需要为 Form_Main 添加 MouseDown 以及 MouseUp 事件,分别用来监测鼠标按下以及弹起的事件信息。再定义两个全局变量,用来标识鼠标左键以及右键是否被按下,代码如下: bool bMouseLeft; // 鼠标左键是否被按下 bool bMouseRight; // 鼠标右键是否被按下 在 MouseDown 事件中输入下面的代码: private void Form_Main_MouseDown(object sender, MouseEventArgs e) { if(e.Button == MouseButtons.Left) // 鼠标左键被按下 { bMouseLeft = true; } if(e.Button == MouseButtons.Right) // 鼠标右键被按下 { bMouseRight = true; } } 在 MouseUp 事件中,我们需要获取鼠标弹...

2015年5月1日 · 7 分钟 · 3289 字 · Kai Wang

扫雷游戏制作过程(CSharp 描述):第六节、内部实现

在进行内部实现之前,我们先来考虑一下扫雷的内部逻辑。首先,我们需要保存每个点上是否有地雷,如果没有地雷,那么要显示与它紧邻的八个格子中一共有多少的地雷。还需保存每个雷区的状态(点开,未点开,红旗,问号)。我们考虑定义两个常量,表示地雷的最大范围: const int MAX_WIDTH = 64; // 最大宽度 const int MAX_HEIGHT = 32; // 最大高度 接下来定义两个数组,用来保存上述两种数据。对于第一类数据,我们使用 -1 表示该区域有地雷,使用数字表示与它紧邻的八个格子中一共有多少地雷;对于第二类数据,我们使用 0 表示未点开,1 表示点开,2 表示红旗,3 表示问号。如下图...

2015年4月30日 · 6 分钟 · 2591 字 · Kai Wang

扫雷游戏制作过程(CSharp 描述):第五节、菜单操作(续)

上一节中,我们还剩下 Setting 和 Rank 两个菜单项目没有设置事件,是因为它们都涉及到了弹出一个新的窗口。这一节,我们将主要介绍创建窗口的方法,以及窗口之间的数据通信。 首先,我们新建一个窗口,在右侧找到解决方案资源管理器,右击 Minesweeper 项目名,选择添加,如图所示: 菜单示意图 选择新建项,如图所示: 菜单示意图 在弹出的窗口中选择 Windows 窗体,并将名称修改为 Form_Setting.cs,单击确定,如图所示: 新建窗口示意图 将新建的窗口 Icon 属性修改为扫雷的图标,将 MaximizeBox 属性修改为 False,将 Name 属性修改为 Form_Setting,将 BackColor 属性修...

2015年4月24日 · 4 分钟 · 1930 字 · Kai Wang

扫雷游戏制作过程(CSharp 描述):第四节、菜单操作

我们现在的程序单击菜单的时候不会有任何反应,这一节我们主要介绍菜单的相关代码,使得菜单能够正常使用。 在第二节中,我们曾经提出希望在对应级别(初级、中级、高级、自定义)的按钮的显示勾,以表示目前的游戏等级。我们有两个时候需要对它进行操作,一个是加载上次游戏设置的时候,一个是在游戏过程中进行设置的时候,我们先介绍第一种情况。按照下图修改代码: /// <summary> /// 选择对应的游戏等级 /// </summary> private void SelectLevel() { if (nWidth == 10 && nHeight == 10 && nMineCnt == 10) { beginnerBToolStripMenuItem.Checked = true; intermediateIToolStripMenuItem.Checked = false; expertEToolStripMenuItem.Checked = false; settingSToolStripMenuItem.Checked = false; } else if (nWidth == 16 && nHeight == 16 && nMineCnt == 40) { beginnerBToolStripMenuItem.Checked = false; intermediateIToolStripMenuItem.Checked = true; expertEToolStripMenuItem.Checked = false; settingSToolStripMenuItem.Checked = false; } else if (nWidth == 30 && nHeight == 16...

2015年4月22日 · 5 分钟 · 2454 字 · Kai Wang

扫雷游戏制作过程(CSharp 描述):第三节、雷区绘制

这一节我们主要涉及界面中雷区的绘制方法。 首先来考虑几个问题。为了保存整个雷区的信息,我们需要哪些数据。显然,除了要保存雷区的宽度和高度(分别定义为宽和高方向上方块的个数)外,还需要保存地雷的数目。这样我们需要用到三个变量 nWidth, nHeight, nMineCnt 分别保存雷区的宽度、雷区的高度以及地雷的数目。 右击窗口,选择查看代码,也可以使用快捷键 F7,如下图所示: 菜单示意图 可以看到这样的代码界面: 代码界面 添加如下所示的代码,用来定义扫雷区域的基本变量,它们的含义在上文或者注释中都有提及: namespace Minesweeper { public partial class Form_Main : Form { int nWidth; // 表示雷区的宽度 int nHeight;...

2015年4月21日 · 6 分钟 · 2665 字 · Kai Wang

扫雷游戏制作过程(CSharp 描述):第二节、界面设计

这一节我们主要介绍关于扫雷游戏界面的设计,此处我们借鉴经典扫雷界面的设计方法,首先需要创建一个菜单栏。具体方法在左边找到工具箱窗口,展开其中的菜单和工具栏,找到 MenuStrip 选项,如图所示: 添加 MenuStrip 只需要双击该条目就可以在窗口中新建一个菜单栏,如图所示: MenuStrip 添加效果 对于这个控件(我们习惯上将窗口中的东西称作为控件),我们还是需要修改它的一些属性,对于个人习惯而言,我习惯于修改它的 Name 属性,这样编程的时候不至于将很多控件混淆。我们将它的 Name 属性修改为“MenuStrip_Main”。单击“请在此键入”,输入“Game...

2015年4月20日 · 5 分钟 · 2174 字 · Kai Wang

扫雷游戏制作过程(CSharp 描述):第一节、创建项目

这一系列的文章主要受许宏旭的启发而来。他目前在连载更新一篇使用 C# 制作五子棋的教程。选择这一项目的主要原因是 Windows 8.1 系统上的扫雷需要前往应用商店下载,显得有些麻烦。因此想自己制作一个。主要采用 C# 语言进行实现。主要功能与原来的扫雷游戏基本相同,进行修改的地方主要是扫雷区的界面。如有不恰当的地方,还望指正。 该项目现已根据文章进度托管在GitHub上,读者可以自行查看。 玩过扫雷的读者应该知道,扫雷需要用到三种图片素材——地雷、红旗、问号。当右击一个方块的时候,会插上红旗,表示游戏者认为该方块内有地雷;再次右...

2015年4月20日 · 3 分钟 · 1121 字 · Kai Wang