基于Java的扫雷游戏设计与实现

攻城狮0829

发布日期: 2020-07-30 11:30:48 浏览量: 59
评分:
star star star star star star star star star star_border
*转载请注明来自write-bug.com

摘 要

扫雷这款游戏有着很长的历史,从扫雷被开发出来到现在进行了无数次的优化,这款游戏变得越来越让人爱不释手了,简单的玩法在加上一个好看的游戏界面,每一处的细节都体现了扫雷的魅力。所以本次的毕业设计我将开发一款扫雷游戏。

本次毕业设计是以JAVA语言作为开发环境,使用Eclipse设计并开发一个类似Windows扫雷的游戏,实现其基本功能。论文首先介绍了课题背景,其次进行了需求分析及可行性分析;然后设计游戏流程,介绍雷区中的雷怎么安放和产生雷的随机算法;最后介绍游戏中可能会触发的各种时间,比如鼠标点击时间和清理掉没有雷的格子,其中鼠标事件包括点击到或没有点击到雷触发的事件和点击到重新开始以及菜单触发的事件,清理掉没有雷的格子就需要使用“递归”的方法来使该功能可以简单的实现。

关键词:扫雷;Eclipse;事件;递归

Abstract

Mine the game has a long history, from the mine was developed to now numerous optimization, the game is becoming more and more let a person fondle admiringly, simple style with a nice game interface, every detail reflects the charm of mine. So I’m going to develop a minesweeper game.

The graduate design study was designed with the JAVA language as a development environment, using Eclipse to design and develop a game like Windows minesweeper to implement its basic functions. The paper firstly introduces the background of the project and analyzes the requirements and feasibility analysis. Then the game process was designed to introduce the random algorithm of how the thunder in the minefield was placed and produced. Finally introduced the game may trigger a variety of time, such as a mouse click on the clear time and there is no ray of diamonds, mouse events including click to or no click to ray trigger events and click to restart and menu trigger events, clearing out squares no ray will need to use the “recursive” methods to make the function can be simple to implement.

Key words: Mine game; Visual Basic 6.0; Affairs; Recursion

1 绪论

1.1 课题背景及意义

在1964年 有一个叫“方 块”的游戏,这是扫雷最原始的版本。后来,这个游戏被改成了另一种游戏,叫做“Rlogic”。在这个游戏中,玩家扮演了一名军队的军人,接受了一项艰难的任务:为指挥中心探路。当然游戏不会这么简单,这条路上充满了地雷,玩家需要小心翼翼的探索出一条没有地雷的安全的道路,如果被雷炸死游戏就会结束。一年后,汤姆•安德森(Tom Anderson)在之前游戏的基础上又编写了一款新的游戏,这就是扫雷游戏。1979年, 两名工程师在计算机的操作系统上搭载了这款小游戏,从此以后扫雷游戏开始风靡全球。如今,越来越多的人喜爱上了这款简单易上手的小游戏,这个小游戏可以在任何时间在任何平台上进行游戏,让人可以在游戏中享受到乐趣并且还能在一定程度上锻炼玩家的思维能力。

扫雷这款游戏有着很长的历史,从扫雷被开发出来到现在进行了无数次的优化,这款游戏变得越来越让人爱不释手了,简单的玩法在加上一个好看的游戏界面,每一处的细节都体现了扫雷的魅力。所以本次的毕业设计我将开发一款扫雷游戏。

扫雷游戏深受大家的喜爱,本次的毕业设计也是迎合大家的喜欢,开发一款扫雷小游戏,同时也可以提高自己编程水平。

1.2 开发工具的选用及介绍

Eclipse是一款非常好用的编译软件,它也经历了很长时间的发展,并且是由许多公司联合开发的免费软件。2011年5月,公布稳 定版4.2;2012年4月公布代号为Ganymeode的4.3版;2013年5月公布代号为Galieleo的4.4版;2013年7月公布代号为Helomios的4.5版;2013年11月公布代号为Indigon的4.6版;2014年3月公布代号为Jiuno的5.1版;2014年7月公布代号为Keplere的5.2版;2015年3月公布代号为Lunam的5.3版;2015年8月公布代号为Marse的5.4版。

Eclipse是目前主流的编写代码的软件,可以支持预编译,在写代码的同时就能知道是否书写错误,而不用等到运行的时候才发现。原本这个软件只能编写Java语言,但是经过多年的开发设计出了许多的插件,将这些插件安装进去以后就可以编写其他语言了,这也就是他被大部分人所喜爱的原因。正是由于插件的使用,Eclipse变得很灵活,可以通过安装插件来实现原本没有的功能,让软件更加的便利。

Eclipse一开始是由两个团队联合设计开发出来的,由于该软件的强大功能使得许多公司纷纷加盟该项目联合开发。而且这个项目是开源的,任何人都能对其进行开发修改,这让Eclipse的名气愈来愈大,后来连甲骨文这种大公司都加入这个项目之中。这种免费的开发软件也很受许多公司的喜爱,通过安装插件可以使用各种语言。

Java语言是一种深受大家喜爱的语言,因为它是面向对象的,所以在理解了这种语言之后就会在代码的设计上有更深刻的理解。

如果没有JDK,你编写的Java代码是无法运行的,这是因为我们需要使用他自带的类库来帮助我们设计,由于不同的软件都可以编写代码,语言规范也就显得尤为重要,所以在开始编写代码之前一定要安装好JDK。

现在在网上是有着许许多多的JDK版本,其中以Sun公司发布的最好,其他公司也有开发并发布出来。有的在性能上甚至超过了Sun公司的JDK,有的则在在执行的效率上高于Sun公司的JDK。但是我们还是选择使用它的原因是因为它是最稳定的JDK,经过多年的开发和完善,是其他JDK所不能相比的。所以我们要熟练的运用它。

1.3 选题目的和意义

经历了大学四年的学习之后,我已经学习了一些关于设计和编程的理论知识,本次的毕业设计运用学过的知识编写一个扫雷小游戏,是对我平时学习成果的一次检验。在设计当中让我的知识在实践中融会贯通并得到提升,并且能发现许多平常发现不了的问题,期望能通过本次的毕业设计让我的能力再一次提高。这次毕设一定会让我收获许多,在今后的工作生涯中能轻松的胜任任何任务。

1.4 本文主要研究的内容

扫雷游戏风靡全球,受到很多人的喜爱。我研究了这个扫雷游戏之后,发现有两个关键点:

  • 第一点是鼠标事件的处理:包括鼠标点击菜单项中按钮的事件,点击雷区中任意一格的事件,点击界面上按钮的事件等

  • 第二点是初始化雷区:包括随机生成雷的位置,界面的初始化,计算周围雷数等

具体要求如下:

  • 扫雷游戏分为三种难度,分别是初、中、高级,点击游戏左上角的“游戏”菜单后会出现“初级”、“中级”、“高级”三种选项。除此之外玩家还可以自定义难度

  • 在玩家选择难度之后游戏将会改变界面大小,并改变雷的总数。当玩家点开第一个格子时雷区开始布雷同时计时开始

  • 若玩家想放弃本局游戏并重新开始的话,可以通过点击扫雷信息统计区中的按钮,来结束当前的游戏并开始新的游戏

  • 当玩家认为某个格没有雷,可以直接用鼠标单击这个格或者把鼠标放在该格子上按下空格键。如果玩家的判断是正确的,则会显示周围8个格子中地雷的总数,如果玩家判断错误,该格子下藏着雷的话,游戏就好结束,系统自动弹框提示玩家失败

  • 若玩家认为某个格下有雷,在该格子上鼠标右键就可以标记一个玩家认为该格是雷的图标,也就是在格子上标记一个小红旗的图案。玩家每标记一个红旗(不管玩家的判断正确与否),界面上的计数区都会把雷数减一

  • 当所有的雷都标记正确后,游戏会自动弹框显示“您真厉害,请输入您的名字,记录上榜!”

  • 若玩家在游戏过程中单击了有雷的格子,游戏失败并且记时停止,游戏会将剩余的雷全部显示出来,自动弹框显示“你输了,请继续努力!”,之后玩家可以开始一局新的游戏

  • 如果玩家不清楚游戏玩法,可以点击菜单栏上的帮助来获取游戏玩法及游戏窍门

  • 对于自定义难度,系统会有一个阈值,行数在9到16之间,列数在9到30之间,地雷数在10到99之间。如果玩家设置的值超过该阈值,系统会自动将超过的数值变成阈值

2 需求分析

2.1 可行性分析

扫雷游戏是一款玩法简单的小游戏,无论是孩子还是老人,都可以在休息的时候玩上一局从而轻松而有效地舒缓压力。而且真正的扫雷高手还可以通过竞速(在最短的时间内完成扫雷)来感受乐趣。

  • 投资可行性:扫雷游戏所占内存少,可以搭载在任意平台,有投资的价值

  • 财务可行性:从受益者的角度来看,不需太多的经费就能开发这款扫雷小游戏

  • 组织可行性:制度可行的项目规划,做好人员的配给,保持组员间的良好沟通,定期开会讨论,确保项目能够准时交付

  • 经济可行性:可以给开发的企业创造效益,给社会增加工作岗位,并且提高人们的生活质量

  • 法律可行性:任何的产品都需要确保它没有触犯法律才能开始设计。但是扫雷游戏并不会触犯任何法律,而且不会和企业之间发生冲突。游戏的开发不会侵犯任何人的利益,也不会违法

  • 技术可行性:扫雷游戏的功能简单,只需稍有经验的开发人员就能轻易开发出来,所以技术方面不是太大的问题,主要需要明白扫雷的玩法才能更好的设计与实现该游戏

2.2 扫雷游戏功能描述

游戏界面可以分为三个模块:菜单栏,游戏数据显示区域以及雷区。菜单栏包括游戏难度的选择和排行榜的查询以及游戏帮助。游戏数据显示区域包括地雷计数区、计时区和重新开始按钮。雷区就是玩家的游戏区域,当玩家在游戏过程中用鼠标点击某一模块,系统会自动作出相应的响应,这就是游戏中的鼠标事件。

当玩家点开第一个格子时雷区开始布雷同时计时开始。然后会在该格子上显示周围8个格子的雷数(如果没有雷则自动点开周围的格子),玩家就需要通过这些数字来判断雷的位置,将是雷的格子标记为小红旗。

若玩家认为已标记的格子时错误的,可以再次右击该格子来取消标记。当某一格子被标记时,对于该格子的单击操作是无效的(防止玩家误点击导致游戏失败)。

如果玩家将某一格周围8个格子中的雷标记了出来,双击该格子会自动将周围的格子点击一遍,这样可以简化玩家的操作。

当玩家将全部的地雷标记出来并且其他的格子点开时,游戏结束。但是如果玩家不小心点到了地雷就会游戏失败,系统自动显示出所有的地雷。如果玩家标识的地雷数量超过了该难度下规定的雷数,计数区会以负数显示超出的雷数并且游戏不会结束。

2.3 扫雷游戏用例图

从上述扫雷游戏功能描述以及用例图可以分析出,整个扫雷游戏中,玩家所能进行的操作有:选择难度、开始游戏、重新开始游戏和记录查询等。

2.4 扫雷游戏功能需求

本次扫雷设计需要实现的主要功能有:

2.4.1 玩家可以选择合适的游戏难度

点击游戏界面左上角菜单栏中的“游戏”菜单,会出现出现“初级”、“中级”、“高级”、“自定义”四种选项。在玩家选择难度之后游戏将会改变界面尺寸,并改变雷的总数。前三种雷数和尺寸都是固定的,无需玩家设置,而自定义则是玩家自己定义的。

2.4.2 进行扫雷游戏

游戏界面包括菜单栏,游戏数据显示区域以及雷区,当玩家点击雷区中的任意一格的时候游戏开始,雷区开始随机布雷,玩家需要在最短的时间内找出雷区中所有的地雷,并加以标识。

扫雷的基本操作包括鼠标左键单击和右键单击两种。其中左键用来点开玩家认为不是雷的格子,右键标记玩家认为是雷的格子。

  • 左键单击:玩家在判断出该格子下没有雷时单击该格子,可以将该格子点开。如果该格子周围有雷就会显示周围雷的数目(由于周围最多只有8个格子,所以最多只能显示8);如果格子上什么也不显示(也就是为空),系统就会自动调用递归的方法打开附近的格子。如果点到了有地雷的格子,那么游戏结束,系统显示所有雷的位置

  • 右键单击:玩家可以通过使用鼠标右键单击来标记自己认为是雷的格子,通过标记可以有效的提高扫雷游戏的效率。再次右击该格子可以取消标记,且格子被标记的时候鼠标单击无效(防止玩家误操作导致游戏失败)

2.4.3 游戏计时

当点击雷区任意一个格子的时候雷区开始布雷同时计时开始,计时标准是一秒增加1。如果游戏失败时,则计时停止。如果玩家开始了新游戏,计时也会重新开始。

2.4.4 标记地雷

当玩家认为格子下有雷时可以右击格子来标记该格子,被标记的格子显示小红旗。再次右击可以取消标记,且格子被标记的时候鼠标单击无效(防止玩家误操作导致游戏失败)。如果玩家标识的地雷的数量超过了该难度下规定的雷数,计数区会以负数来显示超过的雷数并且游戏不会结束。

2.4.5 统计功能

当玩家游戏胜利后会弹框提示并可以输入玩家的名字,确认后本次游戏的记录会被保存。玩家可以点击菜单栏上的“游戏”菜单,再点击其中的“扫雷榜”即可查看游戏的最佳记录。

2.4.6 退出

点击关闭按钮可以结束游戏。

2.5 扫雷游戏界面需求

2.5.1 游戏菜单

玩家有5项可以选择,玩家在点击初级时游戏界面的尺寸会变为初级的大小,雷区重新初始化,变为一共9*9的格子,其中有10颗是地雷;中级一共有16*16个格子,其中有40颗是地雷;高级一共有16*30个格子,其中有99颗是雷。除此之外,玩家还可以自定义难度,在弹框中填写雷数与尺寸。

玩家通过点击鼠标右键来标记自己认为是雷的格子,通过标记可以有效的提高扫雷游戏的效率,再次点击右键可以取消标记。

扫雷榜,记录玩家不同难度的最短时间。

2.5.2 游戏区域

游戏区域由扫雷信息统计区和雷区组成,其中扫雷信息统计区又分为计数区、计时区、重新开始按钮。

雷区的雷数,每个难度对应的雷数都不同,初级、中级、高级分别对应10、40、99个雷。

计数区初始显示的雷数由难度而定,每次标记地雷雷数均减1,如果玩家标记的地雷的数量超过了该难度下规定的雷数,计数区会以负数显示超过的雷数。

当玩家点开第一个格子雷区开始布雷同时计时开始,一秒加1,直到游戏胜利或者游戏失败的时候停止计时。

2.6 扫雷游戏功能模块

游戏在功能上分为6个模块:

  • 游戏界面

  • 布雷

  • 鼠标事件

  • 地雷判断

  • 游戏胜利(结束)

  • 游戏失败(结束)

3 游戏的概要分析与设计

3.1 设计构想

如今世界上很多人都在使用Windows操作系统,所以人们也对系统自带的小游戏了如指掌。扫雷游戏的玩法简单,只要玩家进行一定的判断就可以轻松的游戏,所以玩扫雷的时候可以很轻松的玩。除了游戏本身带给人们的乐趣以外,游戏的玩法也在锻炼玩家的思维,如今大部分人都是依赖脑力劳动,这就可以通过在闲暇的时候玩玩扫雷来锻炼一下自己。所以就可以理解,为什么在各种电子产品上都搭载这个小游戏了。

虽然游戏比较简单,但是还是需要熟悉一下规则。

玩家需要在最短的时间内找出雷区中所有的地雷,并加以标识,其他没有雷的格子全部点开后游戏胜利。但是如果点到了地雷则游戏失败。

游戏的操作很简单,当玩家用鼠标左键点击自己认为不是地雷的格子会点开该格子,用鼠标右键点击格子会标记该格子,再次右击可以取消标记。玩家可以通过雷区中被点开的格子上显示的数字来判断该格子周围8个格子所隐藏的地雷,例如:点开的格子显示数字“2”,则表示该格子周边的8个格子里隐藏着2颗地雷。

如果点开的格子下没有雷且周围8个格子里也没有雷,则系统会自动点开那8个格子,然后递归判断这些格子周围有没有雷。

本次的扫雷游戏设计,需要编写7个Java类:MineaGamae.java类、MineAra.java类、Block.jaav类、BlockVaiw.java类、LayMinas.java类、Record.java类和ShowRecrd.java类。

  • MineGame.java:MineGame类是游戏的入口,用来初始化游戏资源,比如界面尺寸和雷数等。同时也负责难度的转换

  • MineArea.java:MineArea类是布置雷区的雷,除了初始化雷区以外还可以响应玩家的鼠标操作

  • Block.java:Block类是一个POJO类,主要记录了雷区一个个格子的属性,比如名字,周围雷的数目等等

  • BlockView.java:BlockView类用来显示块的属性,并且使用卡片布局来使格子分为了上下两层,当玩家点击格子后,会使下面的属性浮现出来

  • LayMines.java:LayMines类是计算不是雷的格周围雷个数的类,以及设置点选之后的图片样式。创建的对象lay是MineArea中最重要的成员

  • Record.java:Record类是通过IO流将游戏记录储存在本地的文件中,主要实现通关后弹窗提示通关的窗口,以及记录成绩

  • ShowRecord.java:ShowRecord类是显示扫雷记录的类

3.2 流程规划

有三个部分,分别是游戏选择难度后、玩家第一次点击格子和为不是地雷的格子自动点开。

游戏选择难度后,获取该难度设定的雷数与界面尺寸显示界面,但是还没有布雷。当玩家第一次点开格子的时候系统随机布雷并启动定时器,为什么要在点过一次格子之后才布雷呢?这就是要让玩家第一次不会点到地雷,要不然玩家该多郁闷,这样才能提高玩家的游戏欲。之后是最重要的一步,就是如何将格子周围没有雷的格子自动点开,我们可以使用递归的方法来巧妙的判断并点开周围的格子。

整体规划如图3-2所示:

3.3 界面规划

界面规划如图3-3所示:

说明如下:

  • 1:游戏主界面(Interface)

  • 2:菜单(Menu)

  • 3:地雷数显示区(MineNumberArea)

  • 4:重新开始(Restart)

  • 5:扫雷用时显示区(TimeArea)

  • 6:地雷区(MineArea)

3.4 算法思想

3.4.1 随机布雷

扫雷游戏要求在雷区随机布雷,雷数不能太多,这样就没法很好的判断周围是否有雷了;但也不能太少,这样会出现点一下就会点开一大片的空白区域。使用java自带的Math.random()方法产生随机数,经过计算后得到将随机数转换成一个整数,这个整数就是雷的位置的角标。游戏的目标是在将所有的地雷标记出来,并将其它不是雷的格子点开。

3.4.2 计算方格周围雷数

当没有雷的格子被点击后,会显示该格子周围8个格子里所有的雷数,玩家通过这个数字就可以判断出雷的位置,所以周围雷数的计算也很重要。

4 游戏的详细设计

4.1 游戏初始化

玩家点开游戏,此时系统自动加载界面,分别是雷区、菜单区、扫雷数据显示区,如图4-1所示:

游戏界面相对计算机自带的扫雷游戏比较简洁,主要由游戏数据显示区域以及雷区构成。

我们使用ImageIcon对象来存放地雷的图标,可以图标大小最好要小一些,否则会在格子上显示不全。

对地雷区的初始化是很重要的,我们使用一个循环即可实现初始化。玩家点开游戏之后可以点击菜单栏选择扫雷游戏的难度,不同的难度就代表了不同的地雷总数和尺寸,自定义的难度也会设置雷数和尺寸,设置的这些数据全部存放在几个变量之中,当雷区要初始化的时候程序会调用这么变量属性,然后通过一个循环来完成初始化。主要代码如下:

而之前所说的循环初始化其实就是循环的加载组件,雷区就是由一个个组件构成的,通过循环将所有的格子都布置到雷区,然后再随机产生地雷并布置到雷区上。

组件位置的摆放是按照其在数组中的位置来摆放的,所有的格子组件都存放在一个二维数组之中,组件在这个数组中的下标就是他在布局中的位置。

菜单栏是由菜单组件构成的,也就是JMenu组件,这个是菜单组件,用来定义未点击时的菜单样式,这个组件有可以设置JMenauItem组件,这是菜单项的意思,是当玩家点击了菜单后展示出来的子菜单栏。

扫雷游戏的计时区以及计数区又是使用另一种组件完成的,叫做JTextField,这个组件是文本显示的组件,在设置了不可编辑的属性后,该组件在显示的外观上会有变化,边框会变灰一些,意味着该组件不能够点击或者输入。然后使用一个方法随着时间动态的在时间区以一秒为单位增加,计数区则会随着用户标记雷而减一,可以减到负数。

在设置界面的时候还需要进行一些设置,比如设置属性来让玩家在关闭游戏窗口时,系统会自动释放资源,并关闭窗口。

4.2 雷区的布置

当玩家第一次点开格子的时候系统随机布雷并启动定时器,但是为什么要在点过一次格子之后才布雷呢?原来这就是要让玩家第一次不会点到地雷,要不然玩家该多郁闷,这样才能提高玩家的游戏欲。具体实现如下所示:

判断地雷区是否处于可动作状态

判断为左键且该格子为未探测状态

布置地雷

判断地雷应该被布置的位置

4.3 游戏中主要模块的介绍与使用

4.3.1 鼠标事件

我们通过点击鼠标左键或者鼠标右键来完成游戏,使用系统自带的MouseDown和MouseUp事件来响应玩家的操作。

组件名称

组件名称

这两个原型中的参数,Button参数值分别表示玩家用鼠标的左键或者右键进行点击的。其意义如下:

  • 1:左键

  • 2:右键

如果同时按两个按键,那么系统就会传回3,因为点左键是1,点右键是2,一起点就是两个值相加了。

在本次的扫雷设计中,我们会用鼠标的MouseUp事件来响应玩家的操作,其中鼠标左键用来点开玩家认为没有雷的格子,鼠标右键用来标记玩家认为下面藏有雷的格子。使用MouseaUp事件而不用MouseaDown事件的原因是,前者是在当鼠标按键抬起是触发,而后者是当按键按下就触发。假如玩家在点击某一个格子的时候突然发现好像点错了,此时玩家只要继续按下鼠标右键,再抬起的时候就会发现格子被标记成地雷了,现在的游戏一般都有这个功能,这可以有效的提升玩家的游戏体验。

在人机交互的界面上,鼠标的操作是很重要的,但是程序的设计不合理会使鼠标无法发挥应有的功能。在鼠标点击事件中使用MouseUp来响应事件在上面也进行了解释,这样就可以很巧妙的让玩家体会到游戏的贴心之处,可以有效的提升玩家的游戏体验。

当鼠标左键点击格子时

当鼠标右击标识有雷的格子时

4.3.2 地雷及雷区表面探测情况

在雷区的设计上,我使用循环加载组件的方法让雷区布满格子,如果玩家点击了格子就会让该格子下面隐藏的组件显示出来如图4-2和图4-3所示:

地雷随机生成

地雷被标记

玩家通过单击格子来点开格子,右击格子标记地雷。由于使用了两个数组记录地雷的位置以及被点开的信息,所以可以通过两层嵌套循环来判断该格子周围雷的数目,而且系统会点开该格子周围8个格子中没有雷的格子,这又需要用到递归调用来一直进行这个点开格子并验证的过程,直到不符合条件为止。利用这种嵌套循环以及递归调用,都会使一个耗时耗力的问题变得容易解决起来,使得代码结构也变得清晰明了,并且会提高系统的计算速度。

4.3.3 清除未靠近地雷的格子

开始之前需要介绍并学习一下“递归”,递归的狭义解释就是一个方法调用自己本身,通过一个判断语句决定是否结束调用。在代码的设计上也是一种非常重要的代码结构,通过这种方法编写代码,会使得代码结构看起来相当简单明了。但是需要注意的是,如果操作不当会是系统无限循环调用,使得游戏崩溃,所以在编写代码时必须使用判断的语句来控制循环调用的结束,以停止该方法的递归调用。

当玩家在进行游戏时点击了任意一个格子,系统会检测周围8个格子下是否藏雷,如果雷都被标记或者没有雷就会被点开并循环调用继续判断被点开格子周围的雷数。

设计的时候需要考虑的判断条件:玩家点击了某一个格子后判断该格子下是否藏雷;如果没有雷则判断周围8个格的雷数并显示;若雷都被标记出来或者本来就没有雷则点开周围的格子递归判断被点开格子周围的雷。

由于递归是循环调用方法本身,所以需要一个判断语句来结束调用,当被点开的格子周围有雷时在格子上显示雷数并结束递归调用。

递归方法虽然很好但也有一些的缺点,除了结束条件的选取很重要外,如果在扫雷设计中将雷区的尺寸设置过大,而地雷数却很少的话会使的循环调用变慢。所以在游戏的玩法设计上也要小心谨慎,不可以胡乱定义,以免造成系统负担,使得游戏无法顺利进行下去。

代码部分如下所示

我设计的扫雷有在难度的选择上有三种难度,分别是初、中、高级,这三种难度定义的雷数和雷区的尺寸是固定的,假如玩家想要自己定义扫雷的难度可以自己设置雷数和尺寸,只要打开“自定义”配置弹窗,在之后的弹框里按提示输入雷数和尺寸,行数最大为24,列数最大为30,如果玩家设置的雷数超过了范围(比如雷数大于格子的总数或小于零),系统会默认雷数为行数减一与列数减一的乘积。

4.3.5 菜单栏的功能

  • 初级:设置格子总数为9*9,地雷总数为10颗雷,尺寸为300*380然后重新开始游戏

  • 中级:设置格子总数为16*16,地雷总数为40颗雷,尺寸为480*580然后重新开始游戏

  • 高级:设置格子总数为16*30,地雷总数为99颗雷,尺寸为800*500然后重新开始游戏

  • 自定义:设置格子总数为最大24*30,最多雷数为24*30的难度,然后重新开始游戏

  • 扫雷榜: 打开并显示时间最短的扫雷记录,可以进行更新和重新记分

4.4 游戏的判断

4.4.1 游戏成功完成

游戏要求玩家在最短的时间内完成游戏,当玩家将所有的雷标记出来并且其它格子都点开以后游戏胜利,系统会弹出提示框告诉玩家“您真厉害,请输入您的名字,记录上榜!”,系统会记录玩家最短完成游戏的时间。

4.4.2 游戏失败

如果玩家不幸点击到了有雷的格子,该格子的地雷会引爆其他的地雷,游戏失败,系统会将剩下的地雷全部显示出来,并弹框提示“你输了,请继续努力!”,玩家可以选择弹框上的重新开始游戏选项来开始一局新的游戏。

格子类的对象有一个标识该格子是否是雷的属性,通过该属性来判断玩家点到的是不是地雷。在游戏结束时也是通过该属性来判断哪些格子下有雷并显示出来。

具体代码如下所示

4.5 类设计

4.5.1 MineGame类

MineGame类主要负责开始游戏,菜单的设计,以及难度的转换。展示该类的UML图如图4-4所示。

  • 成员变量

    • bar 是窗体的菜单栏变量
    • fileMenu1 是扫雷游戏的菜单,叫做“游戏”
    • fileMenu2 是扫雷的另一个菜单,叫做“帮助”
    • 初级 是扫雷游戏的难度变量
    • 中级 是扫雷游戏的难度变量
    • 高级 是扫雷游戏的难度变量
    • 扫雷榜 是扫雷的统计信息变量
    • mineArea 是MineArea雷的对象,是设计雷区的变量
    • file 是文件变量,用来读取扫雷记录
    • hashtable 是用来临时存放扫雷记录
    • showHeroRecord 是用来显示扫雷记录的变量
  • 成员方法

    • MiwneGaame()通过该方法设置了游戏整体的位置和布局,并实现菜单栏功能,初始化统计信息
    • actionPerformed(ActionEvent e)是响应点击菜单项的方法,通过该方法可以实现选择不同难度调整游戏的雷数和尺寸。玩家点选不同的菜单项会让该方法执行不同的操作
    • main()方法是游戏开始的方法,通过new了一个MineGame的对象来实现游戏的开始

4.5.2 Block类

Block类是一个POJO类,主要记录了雷区一个个格子的属性,比如名字,周围雷的数目等等。展示该类的UML图如图4-5所示。

  • 成员变量

    • Name是记录格子名字的变量
    • isMine是标记格子下有无地雷的变量
    • isMark是标记格子被标记状态的变量
    • mineIcon记录了块的图标的变量
    • isOpen是标记格子的点开状态的变量
    • arounfdMinqeNmber是记录格子周围8个格子中雷的数量的变量
  • 成员方法

    • Block()无参构造方法,以防止创建错误参数的对象
    • Block(String name,int aroundMineNumber,ImageIcon mineIcon,boolean isMine,boolean isMark,boolean isOpen)全参构造方法,可以为变量赋值
    • setNamqe()方法可以设置块的名字
    • getName()获取块的名字
    • setAounMineNuber()方法可以设置块周围雷的数目
    • setMineIicon()方法可以设置块的图标
    • getMineIcon()获取块的图标
    • setIsMinae()方法可以设置块是否是雷
    • getAroundMineNumber()获取块周围雷的数目
    • getIsMine()获取块是否是雷
    • setIsMarek()方法可以设置块是否被标记
    • getIsMark()获取块是否被标记
    • setIsOpen(boolean p)设置块是否被挖开
    • getIsOpen()获取块是否被挖开
    • toString()以字符串的格式输出该对象

4.5.3 BlockView类

BlockView类继承了JPanel类,主要布置每一个格子的布局,用来定义每个格子的属性。显示该类的UML图如图4-6所示。

  • 成员变量

    • blockeNameOrIcona 该变量用来显示格子的名字和图标属性
    • blockeCoverq 是一个标记变量
    • card 卡片式布局,显示第一次添加的组件
  • 成员方法

    • BlockView()构造方法,初始化变量,设置块上属性显示的位置为居中,并添加组件
    • giveView()方法,给每一个格子提供视图,如果该格子下有雷,会调用方法赋予该格子“地雷”的图标,但被覆盖在下面。如果下面没有雷,会显示该格子周围地雷的数目,同样会被覆盖住。该方法被调用时显示雷或者数字
    • seeBlouckNamerOrIcon()方法是用来让块的属性显示出来
    • seeBlouckCovear()方法是让cover遮盖块的属性
    • getBlouckCovear()方法是得到用来遮盖的按钮

4.5.4 Record类

Record类主要实现通关后弹窗提示通关的窗口,以及记录成绩。当玩家扫雷成功时,该对象提供了保存成绩到文件的界面。展示该类的UML图如图4-7所示。

  • 成员变量

    • time 用来给游戏计时
    • grade 记录难度的变量
    • key 表示一个判断的变量
    • message 记录成绩的数据变量
    • textName 一个文本显示组件
    • label 一个可输入文本输入框组件
    • 确定,取消 两个按钮组件,一个代表确定,一个代表取消
  • 成员方法

    • Record() 构造方法,初始化变量,设置窗口是否可以调整大小
    • setGrade() 方法可以设置成绩
    • writeRecord() 方法可以读写记录,如果没有记录会先创建一个新的文档来保存记录,下次直接修改覆盖记录
    • setTime() 方法是用来设置时间的
    • actionPerformed(ActionEvent e) 方法是响应鼠标的点击事件的方法,当玩家点击弹窗上的任意位置都会触发,但是只有点到正确的位置才会执行操作。比如点击确认,就可以把玩家的游戏记录存放到本地的文件中

4.5.5 ShowRecord类

ShowRecord类是显示扫雷记录的类。展示该类的UML图如图4-8所示。

  • 成员变量

    • file记录成绩的文档
    • name名字
    • hashtable 是记录成绩的变量
    • show是一个显示成绩的按钮组件变量
    • Rescore 是一个初始分数的按钮组件变量
    • Label1[] 显示成绩的组件
    • Label2[] 显示成绩的组件
    • Label3[] 显示成绩的组件
  • 成员方法

    • ShowRecord() 方法是该类的构造方法,初始化成员变量
    • readAndShow() 方法会把在文档中记录的玩家通关信息筛选出来(按游戏完成是花费的时间最短为条件筛选),并显示到弹出的对话框中
    • actionPerformed(ActionEvent e)方法是响应玩家操作的方法,当玩家想要显示游戏记录的时候系统会响应玩家的要求并调用显示成绩的方法,在弹框中刷新成绩

4.5.6 MineArea类

MineArea类主要用于雷区的初始化以及鼠标事件的响应。展示该类的UML图如图4-9所示。

  • 成员变量

    • reStart 是用来显示一个重新开始的按钮
    • block 是一个二维数组,定义了所有雷区的格子
    • blockView 是一个二维数组,是给每一个格子提供显示视图的
    • lay 是负责定义每一个格子下有雷或者没有雷
    • row, colum 是负责记录雷区行列数的变量
    • mineCount 是记录地雷总数的变量
    • markMount 是记录玩家标记的地雷数的变量
    • mark 是ImageIcon类型的变量,用来存放地雷图标
    • time 是记录时间的变量
    • grade 是记录难度的变量,分别有“初级”、“中级”、“高级”三种难度
    • pCenter 是JPanel类型的变量,定义布局中部的控件
    • pNorth 是JPanel类型的变量,分别位于布局的北部的控件
    • showTime 是显示扫雷时间的变量
    • showMareedCoint 是显示玩家标记后剩余的雷数的变量
    • record 是一个对话框变量,用来显示玩家的最好记录,当玩家点击菜单中的英雄榜时会显示该对话框
    • lose 是游戏失败时显示的对话框变量
    • spendTime 是一个标记变量
    • panel 一个轻量级容器变量,嵌套在对话框中
    • str 显示失败的提示语的一个文本框变量
    • reStart1 是一个按钮对象,位于失败对话框里,玩家点击后会触发与reStart一样的操作
  • 成员方法

    • MineArea()方法是该类的构造方法,初始化组件和一下对象,设置字体颜色、边框颜色等,并调用初始化雷区的方法来初始化雷区
    • initMineArea()方法用来设置雷数和游戏界面所有格子的数量,初始化雷区
    • initMine()方法是真正执行初始化的方法
    • setRow(int row)方法用来设置行数
    • setColum(int colum)方法用来设置列数
    • setMineCount(int mineCount)方法用来设置地雷总数
    • setGrade(int grade)方法用来设置难度
    • actionPerformed(ActionEvent)方法是响应鼠标点击格子的事件的方法,当点击的格子下面没有雷,该方法会显示该格子周围雷的数目,有雷则显示雷的图标
    • show()方法是显示格子内容,并且使用递归调用来显示周围格子的内容,直到这个格子周围有雷
    • mousePressed(MouseEvent)方法响应玩家对格子进行的鼠标左键单击事件和鼠标右键点击事件
    • inquireWin()方法是在玩家在游戏过程中满足获胜条件是触发的方法,同时会调用其他方法弹框提示玩家游戏结束

4.5.7 LayMines类

LayMines是计算不是雷的格周围雷个数的类,以及设置点选之后的图片样式。标明该类的UML图如图4-10所示。

  • 成员变量

    • mineIcon 图片资源变量
  • 成员方法

    • LayMines() 构造方法,定义图片资源
    • layMinesForBlock(Block block[][], int mineCount) 方法会判断是否是第一次点击格子,如果玩家是第一次点击格子,开始随机产生雷,但是雷不会布置到第一次点的格子上。如果不是第一次点击且该格子没有雷时会计算周围8个格子中有雷的数目并显示出来

5 游戏实现

5.1 游戏难度自定义

选择难度以及游戏自定义

初级难度

中级难度

高级难度

自定义难度

如图5-1所示,玩家可以自己选择游戏难度,其中有初级,中级,高级以及自定义四种难度,所对应的游戏界面的尺寸也不相同,以及地雷的总数也不相同,雷数越多则难度越大,同时玩家可以自定义游戏难度,通过输入行列数以及地雷数设置游戏界面的大小以及难度。

如图5-2、图5-3、图5-4、图5-5所示,分别展示了初级、中级、高级以及自定义难度的游戏界面尺寸和雷数。

5.2 扫雷

5.2.1 玩家通过右键进行扫雷,并显示小红旗

玩家在游戏过程中会对某一格周围是否有雷进行判断,当玩家认为格子下有雷时就可以通过使用鼠标右键点击该格子,将该格子标识为小红旗如图5-6所示。

5.2.2 玩家因触碰到雷而导致游戏结束

如图5-7所示,当玩家在点开了有雷的格子时,游戏失败,系统会自动将所有的地雷显示出来,并且会弹出一个窗口提示玩家:“你输了,请继续努力!”。除此以外还有两个选项,当玩家选择重新开始按钮时,游戏界面初始化,雷区中的雷全部取消,等待玩家第一次点击格子后开始布雷;如果用户点的是取消的话,就可以关掉这个提示的弹框。

5.2.3 玩家扫雷成功

如图5-8所示,当所有的地雷用都被玩家用小红旗标识出来,并且非雷的格子也被点开时游戏结束,计时停止,系统弹框提醒玩家“您真厉害,请输入您的名字,记录上榜!”,玩家可以在这个界面输入自己的名字来保存扫雷成绩。

5.2.4 玩家游戏数据显示

如图5-9所示,每当玩家成功扫完所有的雷后,系统会自动的记录本次的成绩,保存在本地的txt文档中,内容是三种难度,玩家姓名以及对应难度玩家所用的最少游戏时间。当玩家点击查看英雄榜的时候系统默认只显示三种难度和匿名。

最佳成绩显示图

重新记分显示图

如图5-10所示,玩家点击关闭时此窗口会关掉这个弹窗,当点击重新记分时,统计信息会清空,点击显示成绩就好刷新并将历史最好的成绩显示出来。界面也会发生变化,可以显示出游戏用时。

5.3 程序打包发布过程

至此扫雷游戏已经编写好了,我们可以将这个游戏打包发布,这就需要利用jar.exe命令来将编写好的扫雷游戏的class文件打包发布。

  • 编写清单文件:首先需要使用“记事本”,根据要求自己编写一个清单文件,格式和内容要和这里给的样子一样,具体内容如下:

将清单文件保存到E:\workspace\扫雷\bin\com\zx\mine中,也就是和编写的扫雷游戏程序生成的字节码存放的位置相同,保证这些文件放在一个目录下。

需要注意的是,清单文件中的所有内容均为键值对的形式存放,键值直接必须空一个空格。

  • 生成JAR文件:E:\workspace\扫雷\jarcfmGame.jarMymoon.mf*.class,这条命令中有一些参数需要明白:
    • 参数c意味着要让系统生成一个文件,这个文件叫做JAR
    • 参数f意味着要让系统产生JAR文件的名字
    • 参数m意味着显示清单文件的名字

最后就可以将这个生成的JAR文件复制到任何一个安装了Java运行环境(电脑上的jdk版本不能太低)的电脑上,玩家就可直接用鼠标双击图标来运行自己编写的扫雷小游戏了。

6 游戏测试结果

6.1 游戏难度自定义测试

游戏难度自定义测试用例

预期结果 选择不同的难度后可以正确的初始化雷区
输入条件 分别点击初级、中级、高级和自定义
测试结果 点选不同难度后系统会自动改变雷区大小和地雷数

游戏难度以及自定义测试

初级难度测试

中级难度测试

高级难度测试

自定义难度测试

如图6-1所示,本次扫雷游戏设计将游戏的难度设定为初、中、高以及自定义四种难度,前三种难度对应的游戏界面的尺寸以及地雷总数是不同的,难度越大雷数越多,尺寸也越大,玩家扫雷时就需要更加的动脑思考才能通关。除了固定的难度以外还可以自定义难度,玩家需要自己输入尺寸与雷数,系统根据玩家的要求生产新的游戏,难度可以更加的灵活,这样可以让玩家更满意。

图6-2、图6-3、图6-4、图6-5测试了四种难度的选择,由图可以看出难度的选择功能正常,可以自由变换尺寸和地雷总数。

6.2 扫雷测试

扫雷胜利测试用例

预期结果 成功的将所有地雷标记出来后,游戏可以立马结束且会弹框提示输入玩家名字
输入条件 将所有地雷标记并将非雷格子点开
测试结果 游戏结束并且显示了要求玩家输入名字的弹框

扫雷失败测试用例

预期结果 点击了有雷的格子后游戏可以立马结束且弹框提示玩家游戏失败
输入条件 点击有雷的格子
测试结果 游戏正确的结束且弹框提示了游戏失败的提示

游戏完成并且扫雷成功测试

如图6-6所示,玩家可以通过左键单击格子点开格子,右键单击标识地雷的方式完成游戏。当玩家将所有的地雷都标识出来且其他的格子都被点开的情况下,游戏胜利。系统会弹框提示玩家成功完成了游戏任务“您真厉害,请输入您的名字,记录上榜!”。玩家可以在弹出的弹框中输入自己的名字,若不输入则默认为匿名,然后系统会保存玩家的游戏记录。当玩家点击扫雷榜的时候可以查看自己用时最短的游戏记录。

游戏完成但是扫雷失败测试

如图6-7所示,玩家可以通过左键单击格子点开格子,右键单击标识地雷的方式完成游戏。当玩家在进行扫雷游戏的时候,不小心点击了有雷的格子,这时候地雷被引爆了,所有未被标记的和已被标记的都被引爆,游戏结束。此时系统会自动将所有的地雷显示出来,方便玩家查看之前标记的正确与否,可以总结经验。然后系统弹框提示“你输了,请继续努力!”,玩家可以点击重新开始的按钮重开游戏,继续挑战扫雷游戏,也可以选择结束游戏。

6.3 玩家游戏数据显示测试

最佳成绩测试用例

预期结果 点击“最佳成绩”按钮时会显示玩家最佳的游戏记录
输入条件 打开游戏的扫雷榜,点击“最佳成绩”按钮
测试结果 游戏可以正确的显示玩家的游戏记录

重新记分测试用例

预期结果 点击“重新记分”按钮时会清除玩家以往的游戏记录
输入条件 打开游戏的扫雷榜,点击“重新记分”按钮
测试结果 点击按钮后游戏记录消失,再点击“最佳成绩”按钮只会显示默认的成绩

扫雷榜测试

最佳成绩测试

重新记分测试

如图6-8和图6-9所示,玩家在进行游戏时,如果成功的扫完雷,系统会提示并保存游戏记录。在扫雷榜上玩家可以进行查看。但是当玩家反复通关后,系统会自动的将用时最短的扫雷记录显示出来,所以玩家在查看记录的时候只能看到最快一次通关的记录。

通过图6-10可以看出,当玩家点击了“重新记分”按钮后,之前游戏记录都会被清除掉,只会显示默认的数据:时间为999秒,名字是匿名。

6.4 游戏数据显示区测试

计时区显示测试用例

预期结果 第一次点击雷区的格子时,计时区开始计时,游戏结束时计时停止,重新开始游戏时,计时归零
输入条件 点击雷区的任意一格,然后结束游戏,最后点击“重新开始”按钮
测试结果 当点击雷区任意一格后计时开始,计时正常。然后点击有雷的格子结束游戏发现计时停止。点击“重新开始”后计时区的计时正确归零

开始计时测试

计时停止测试

重新计时测试

如图6-11,图6-12,图6-13所示,当点击雷区中的任意一格后,计时区开始正常计时。当游戏结束时计时区的计时就会停止,最后点击了“重新开始”后计时区的计时归零。

地雷数显示区测试用例

预期结果 标记地雷后计数区的数字会减1,如果标记数超过地雷数,计数区会用负数显示
输入条件 先标记一颗地雷,然后将所有的地雷标记出来
测试结果 标记一颗地雷后,计数区可以正确的减少1个,然后当所有的地雷全被标记后,如果继续标记,计数区可以正确的以负数表示

计数区测试

计数区负数显示测试

如图6-14,图6-15所示,当标记了一颗地雷后计数区中的数字会相应的减少一个,表示有一颗雷被找到了。但是如果标记数超过了地雷的数目,计数区会以负数显示,表示有的地雷标记错了。

6.5 递归算法测试

递归调用测试用例

预期结果 当点击一个周围八个格子中都没有雷的格子时,系统会将这8个格子也点开
输入条件 点开一个周围没有雷的格子
测试结果 系统正确的将周围的八个格子点开,如果这些格子中周围的格子没有雷的话还会自动点开

递归算法测试

如图6-16所示,当点击一个周围八个格子中都没有雷的格子时,系统会将周围的格子点开,被点开的格子也会显示周围的地雷数。如果被点开的格子周围还是没有地雷,系统就会递归调用再把周围的格子点开。

扫雷游戏的代码编写完成,且基本功能也实现了,虽然与电脑上自带的扫雷游戏相比在界面上还是有着一些差距,一些小细节也没有完善,但已经让我很满意了,我会在以后继续完善这些细节,让这个扫雷游戏变得愈来愈好玩。在简单的测试后,该游戏也达到了我的预期,所以本次的设计就到此结束了。

参考文献

[1] 耿祥义.Java大学实用教程[M].北京:清华大学出版社,2009.

[2] 冯锋,王运坚.Visual Basic 程序设计基础教程[M].西安:电子工业出版社,1999。

[3] 王鹏.JavaSwing图形界面开发与案例详解[M].北京:清华大学出版社,2008。

[4] 李怀明.Visual Basic 6.0 中文版 参考详解[M].北京:清华大学出版社,1999。

[5] 丁振凡.Java语言实验教程[M].北京:北京邮电大学出版社,2005。

[6] 郑莉.Java语言程序设计[M].北京:清华大学出版社,2006。

[7] 伍俊良.VB课程设计与系统开发案例[M].北京:清华大学出版社,2002。

[8] 孙全党,王吴迪,赵枫朝.Java程序设计应用教程[M].北京:电子工业出版社,2006。

[9] 雷之宇.Java项目开发实践-网络篇[M].北京:中国铁道出版社,2005。

[10] 赵玉阳.Java从入门到精通[M].北京:清华大学出版社,2006。

[11] 何斌,刘醒.Visual Basic 6.0 应用指南[M].成都:四川大学出版社,1998。

[12] 毕广吉.Java程序设计实例教程[M].北京:冶金工业出版社,2007年。

[13] 李善茂.Visual Basic 6.0 高级编程技巧[M].西安:电子工业出版社,1999。

[14] 王保罗.Java面向对象程序设计[M].北京:清华大学出版社,2003年.人民邮电出版社,2004

[15] 刘腾红,孙细明.信息系统分析与设计[M].北京:科学出版社,2003年。

[16] 林邦杰,彻底研究java[M].北京:电子工业出版社,2002年。

[17] 刘京华. Java Web整合开发王者归来[M].北京:清华大学出版社,2010。

[18] 唐任仲.工程应用软件开发技术[M].北京:化学工业出版社,1999。

[19] 谭浩强.Visual Basic 6.0 中文版 提高与应用[M].西安:电子工业出版社,1999。

[20] (美)阿诺德,Ken Arnold,等. Java程序设计语言[M].北京:人民邮电出版社,2006.

[21] Bruce Eckel. Thinking in Java[M]. Upper Saddle River, New Jersey, USA: Prentice Hall, 2006.

[22] Holger Eichelberger,Klaus Schhmid.Flexible resource monitoring ofJava programs.[J].The Journal of Systems & Software,2014 Elsevier.

[23] Joshua Bloch. Effective Java[M]. Piscataway, N.J: IEEE Press, 2009.

[24] oug Twilleager,Jeff Kesselman,Athomas Goldberger,Daniel Petersen,Juan Carlos,Soto,Chris Melissinos.Java Technologies for games.[J].Computers in Entertainment(CIE),2004,Vol.2(2),pp.18-18 ACM.

上传的附件 cloud_download Java扫雷游戏的设计与实现.zip ( 1.12mb, 1次下载 )
error_outline 下载需要14点积分

发送私信

37
文章数
5
评论数
最近文章
eject