基于Java的扫雷课程设计(DOC)

基于Java的扫雷课程设计(DOC)
基于Java的扫雷课程设计(DOC)

《算法设计与分析》课程设计

扫雷游戏设计

班级计科1003班

姓名

指导教师

开发时间2012.12.18

湖南涉外经济学院信息科学与工程学院

2012年12月

摘要

扫雷游戏是Windows操作系统自带的一个小游戏,过去的几年里Windows 操作系统历经数次换代,变得越来越庞大、复杂,但这个可爱的小游戏在任何版本的Windows操作系统里去地依然保持着原貌。但几乎每个电脑使用者都接触过它,并且深爱着这款小游戏。

游戏上手极其简单,但是要熟练地掌握其中的操作及找出雷的技巧,难度却不低。作为家喻户晓老少皆宜的大众游戏,其普及程度可以说是史上任何一款游戏都无法相比的。

游戏的操作方面主要以鼠标为主,当鼠标指针对准未翻开的方块按下左键时即表示翻开方块,当鼠标指针对准未翻开的方块按下右键时即表示标示或疑示地雷,反复按下右键则方块会以未标示→标示→疑似三者关系不断循环。游戏者可以通过地雷区内的数字提示了解以数字为中心的其周边八个方格内所含的地雷数,假若翻开的方块显示数字“3”,则表示以其为中心的周边方块内藏有3个地雷。当按下的方块不是地雷,且周边八个方块也都没有地雷时,方块会以被翻开方块的八个方向将空白方块翻开。。

扫雷游戏是比较经典的一款小游戏,实现它的方法很多,可以用很多不同算法和语言实现,如C,C++,VB,Jave,C#等。本论文研究的是以java为开发环境,设计并开发一款扫雷游戏,其功能类似于Windows操作系统自带的扫雷游戏。论文首先介绍了制作游戏的整体思路及整个游戏设计的流程规划,然后介绍了雷区的布置及地雷随机产生的实现方法;重点介绍了在游戏过程中各事件的处理,其中又以鼠标事件和清除未靠近地雷区方块这两方面最为重要,鼠标事件是利用鼠标所发出的信息了解使用者的意图,进而做出相对应的动作。

关键词:java;扫雷;课程设计;

目录

第一章引言 (2)

1.1 课题背景及意义 (2)

1.2开发的目的以及意义 (2)

1.3关于本课题 (3)

第二章游戏的总体分析 (4)

2.1 游戏功能简介 (4)

2.2 扫雷游戏的基本要求 (4)

2.3 功能需求分析 (5)

第三章游戏的具体分析 (6)

3.1 总体功能图 (6)

3.2 主要功能设计流程 (7)

3.2.1 总体流程图 (7)

图3-2-1 总体流程图 (7)

3.2.2雷区设计流程图 (8)

3.2.3排行榜设计流程图 (9)

3.3各个类的详细介绍与关键代码 (9)

3.3.1 类之间关系图 (9)

3.3.2 MainFrame类 (10)

3.3.3 LEDNumber类 (12)

3.3.4 MineGrid类 (13)

3.3.5 AboutDialog类 (13)

3.3.6 CustomDialog类 (14)

3.3.7 ImageFactory类 (15)

3.3.8 UserDialog类 (15)

3.3.9 LevelInfo类 (15)

3.3.10 LogDialog类 (17)

第四章游戏的实现 (19)

4.1游戏的初级界面 (19)

4.2游戏的中级界面 (20)

4.3游戏的高级界面 (21)

4.3 游戏的打包发布过程 (22)

第五章结论 (24)

参考文献 (25)

第一章引言

1.1 课题背景及意义

扫雷最原始的版本可以追溯到1973年一款名为“方块”的游戏。不久之后,“方块”被改写成了游戏“Rlogic”。在“Rlogic”里,玩家的任务是作为美国海军陆战队队员,为指挥中心探出一条没有地雷的安全路线,如果路全被地雷堵死就算输。两年后,汤姆·安德森在“Rlogic”的基础上又编写出了游戏“地雷”,由此奠定了现代扫雷游戏的雏形。1981年,微软公司的罗伯特·杜尔和卡特·约翰逊两位工程师在Windows 3.1系统上加载了该游戏,扫雷游戏才正式在全世界推广开来。

在计算机逐步渗入社会生活各个层面的今天,计算机已经成为了人们日常生活中的一部分,越来越多的人使用计算机办公、娱乐等等。在这其中,系统自带的小游戏也占据了相当重要的地位,与那些网络游戏和3D游戏相比,它有编写简单容易上手等特点,非常适合人们在完成工作的时候适当的娱乐要求。这些小游戏大都是以益智和娱乐为目的,不仅给紧张工作的人们以放松,还可以让人们的大脑得到开发。这些小游戏包括扫雷,弹球,纸牌等等。而本课题就是扫雷游戏的设计。

1.2开发的目的以及意义

大学以来各门专业课程的学习,让我综合知识全面提升了很多。为了提高自己的动手能力,将知识灵活的运用,此次我设计了一个扫雷程序。希望将书本上所学的理论知识与实际相结合,通过本次的程序设计使自己在程序的开发和设计上有新的认识并能有所提高。也对于我们以后工作能力的培养具有重要意义。

1.3关于本课题

至少需实现的主要功能(也可以加上一些扩展功能):

(1)用户可以自定义级别并且可以任意输入雷数;

(2)具有计时功能;

(3)可以查看英雄榜。

可以不实现的功能:

(4)可以不做问号;

(5)可以不做鼠标左右两键同时操作;

(6)可以不做鼠标移动。

第二章游戏的总体分析

2.1 游戏功能简介

扫雷游戏的基本功能:

点击鼠标左键于雷区,如果雷区有雷,显示所有的地雷后游戏结束。若无雷,则显示周围雷数。如果周围没雷的话,则查看周围八个区域是否有雷直到有雷为止并显示,这其实是一个递归过程。点击鼠标右键于雷区,则将其置为有雷而不管是否真的有雷。用户可选择初、中、高三级也可自定义雷数和区域大小。雷区左上角显示总雷数减去被标明有雷区域的数目。雷区右上角显示扫雷的时间。将雷全部扫清或失败后显示成功或失败的对话框。

下面是该游戏的几大功能:

开局:首先选择游戏等级,然后生成不同等级的雷区界面。游戏等级分为三级:各等级方块数为——初级、中级、高级;雷区每个方块下面或埋藏有1个地雷,或者没有地雷;

挖雷:将光标移到某个方块,可挖开它;若所揭方块下有雷,则踩雷,此时所有含地雷的块都标记该局游戏失败);如果方块上出现数字,它代表在它周围的8个方块中共有多少颗地雷;

标记地雷:在光标所在的某个方块上右击,则标记此块下埋着地雷(有可能也是误标)。每标记一个地雷,地雷数减少1;

2.2 扫雷游戏的基本要求

Windows 2000/XP系统提供的扫雷游戏是一个很有趣的游戏。本章的课程设计使用Java语言编写一个与其类似的扫雷游戏。具体要求如下:

(1) 扫雷游戏分为初级、中级和高级三个级别。单击游戏菜单可以选择“初级”、“中级”和“高级”。

(2) 选择级别后将出现相应级别的扫雷区域,这时用户使用鼠标左键单击‘“开始”便启动计时器。

(3) 用户要揭开某个方块,可左键单击它。若所揭方块下有雷,用户便输了这一局,若所揭方块下无雷,则显示一个数字,该数字代表方块的周围的8个方块中共有多少颗雷。

(4) 如果用户认为某个方块下埋着雷,单击右键可以在方块上标识一个用户认为是雷的图标,即给出一个扫雷标记。用户每标记出一个扫雷标记(无论用户的标记是否正确),程序将显示的剩余雷数减少一个。

(5)当用户点中雷时,将有“你输了”的提示出现,胜利时,将有“你赢了”的提示出现。

2.3 功能需求分析

本程序为java课程设计。参考Windows自带的扫雷游戏做了简化。用java 编写,采用了Swing 界面。实践了java课程多方面的内容。

本程序实现了主要游戏的主要方面,单游戏固定为10 x 10 格,难度三级:12, 24, 36。主要实现了如下算法:单击某行某列后产生不在单击处引爆的地图。出现空格后引发递归的清空算法。检测是否所有地雷都被标记,且没有多标的胜利检测算法。控制一个计数器产生计时效果的计时器算法。等侯用户单击返回的线程。以及可区分用户鼠标左键,右键和左右两键单击的事件处理方法。

程序设计主要考虑了程序的完整性和规范性。界面符合Windows常规,主要通过菜单和按钮与用户交互。所有菜单项都实现了响应功能。且主界面多用图标示意,较美观。

第三章游戏的具体分析3.1 总体功能图

图3-1 总体功能图

3.2 主要功能设计流程 3.2.1 总体流程图

图3-2-1 总体流程图

开始

定义并初始化按钮,菜单等

事件处理

菜单 按钮

重新开始

方块

开局 初级 高级 中级

自定义 英雄榜

退出

展示相应效果

N

是否点中雷

结束

Y

3.2.2 雷区设计流程图

开始

开始

定义并初始化MineGrid 类

获取相应的设置,并为方块产生随机数字赋值

计数器数小于等级雷数

存放赋值雷区,计数器加1

鼠标是否点击处理周围信息,并显示相应效果

Y

N

Y

N

图3-2-2 雷区设计流程图

3.2.3 排行榜设计流程图

开始

结束

读取游戏级别以及记录

游戏是否完成

完成时间是否更短

更新原始记录

并且保存

Y

N

N

Y

图3-2-3 排行榜设计流程图

3.3各个类的详细介绍与关键代码 3.3.1 类之间关系图

图3-3-1 类之间关系图

3.3.2 MainFrame类

MainFrame主程序类是整个程序的入口,通过package nicholas.game.mine;包将其放在nicholas的game下的mine子文件夹内,继承了JFrame并实现了ActionListener、实现了主界面各控件的布局、led灯,时间计数器,级别,失败和成功,各种状态的初始化。还实现了从mine文件里读取信息和保存信息并实现鼠标双击单击,双击,移动时发生的事件。其关键性代码如下:

private class StatusMouseAdapter extends MouseAdapter {

private boolean mouseIn;

private boolean mouseDown;

private Icon icon;

public StatusMouseAdapter() {

super();

}

public void mouseEntered(MouseEvent me) {//组件按下时

mouseIn = true;

if(mouseDown) {

statusButton.setBorder(BorderFactory.createLoweredBevelBorder());

icon = statusButton.getIcon();

statusButton.setIcon(ImageFactory.getInstance().getImageicon(18));

}

}

public void mousePressed(MouseEvent me) {//组件释放时

mouseDown = true;

statusButton.setBorder(BorderFactory.createLoweredBevelBorder());

icon = statusButton.getIcon();

statusButton.setIcon(ImageFactory.getInstance().getImageicon(18));

}

public void mouseReleased(MouseEvent me) {

mouseDown = false;

statusButton.setIcon(icon);

statusButton.setBorder(BorderFactory.createRaisedBevelBorder());

if(mouseIn) restartGame();

}

public void mouseExited(MouseEvent me) {

mouseIn = false;

if(mouseDown) {

statusButton.setIcon(icon);

statusButton.setBorder(BorderFactory.createRaisedBevelBorder());

}

}

}

public void mouseEntered(MouseEvent me) {//鼠标按下current = (MineGrid)me.getSource();

if(leftDown&&rightDown) {

pressAround(current);

} else if(leftDown) {

pressGrid(current);

}

}

public void mouseReleased(MouseEvent me) {//鼠标释放时if(current.isNormal())

statusButton.setIcon(ImageFactory.getInstance().getImageicon(17));

int x = current.getXpos();

int y = current.getYpos();

if(leftDown) {//左击

leftDown = false;

if(firstClick) {

timeThread = new TimeThread();

timeThread.start();

firstClick = false;

//改变

if(mode[x][y]) {

int i,j;

do {

i = (int)(Math.random()*xBound);

j = (int)(Math.random()*yBound);

} while(mode[i][j]);

mode[x][y] = false;

mode[i][j] = true;

}

}

if(rightDown) {//右击

releaseAround(current);

rightDown = false;

if(middle) {

middle = false;

}

if(current.isClicked()) clickGrid(x,y,2);

} else {

if(current.isNormal()) clickGrid(x,y,1);

}

} else {

rightDown = false;

}

}

public void mouseExited(MouseEvent me) {//鼠标停止时

current = (MineGrid)me.getSource();

if(leftDown&&rightDown) {

releaseAround(current);

} else if(leftDown) {

releaseGrid(current);

}

}

private void pressGrid(MineGrid g) {//按下方格时

if(!g.isNormal()) return;

g.setIcon(ImageFactory.getInstance().getImageicon(0));

}

private void releaseGrid(MineGrid g) {//释放方格时

if(!g.isNormal()) return;

g.setIcon(ImageFactory.getInstance().getImageicon(9));

}

3.3.3 LEDNumber类

LEDNumber类:把数字格式化为液晶字体图像

private int numberSegment[][] = {

{0, 1, 2, 3, 4, 5 }, //0

{1, 2 }, //1

{0, 1, 3, 4, 6 }, //2

{0, 1, 2, 3, 6 }, //3

{1, 2, 5, 6 }, //4

{0, 2, 3, 5, 6 }, //5

{0, 2, 3, 4, 5, 6 }, //6

{0, 1, 2 }, //7

{0, 1, 2, 3, 4, 5, 6 }, //8

{0, 1, 2, 3, 5, 6 } //9

};

用二维数组numberSegment来存储数字,实现界面如图3-3-3所示。

图3-3-3 LED样式的数字

3.3.4 MineGrid类

MineGrid类:格子

用来设置网格的状态、大小及位置信息。

3.3.5 AboutDialog类

AboutDialog类:帮助文档,关于扫雷文档的说明。

AboutDialog类用package nicholas.swing将其放在了nicholas下的swing文件夹下,它继承了JDialog类,并实现了ActionListener接口。

jLabel为其创建了文本标签,jButton创建了按钮,JTextArea创建了文本区域。当用户运行扫雷程序时,点击如图3-3-5所示的帮助菜单出现如图3-3所示的界面。

图3-3-5 关于扫雷界面图

图3-3 关于扫雷界面图

3.3.6 CustomDialog类

CustomDialog类:自定义雷区

通过Jlabel文本标签,接收其高度,宽度,和雷数。实现界面如下:

3.3.7 ImageFactory类

ImageFactory类:图片资源类

ImageFactory类通过package nicholas.game.mine;将其存放在nicholas 下的game下的mine文件夹内,通过引入包import javax.swing.ImageIcon;来实现对图片的各种操作, ImageIcon images[]数组是用来存放各图片。供其它类进行调用。并采用Java里的单例模式保证其对象的唯一性。

3.3.8 UserDialog类

UserDialog类:游戏级别的选择

UserDialog类用package nicholas.game.mine; 将其放在了nicholas下的game下的mine子文件夹内,字符串数组String[] level = {"初级","中级","高级"}初始化各级别的大小和雷数,并通过一个Jlabel空间接手玩家的信息,将其写入文件。

3.3.9 LevelInfo类

LevelInfo类:级别设定

public static final LevelInfo DEFAULT_LEVEL[] = {

new LevelInfo(9, 9, 10),

new LevelInfo(16, 16, 40),

new LevelInfo(16, 30, 99)

};

定义了一个常量数组初始化各级别的默认大小和雷数,还用了一个把各级别的玩家的信息写入文件中的类LevelLog:

class LevelLog implements Serializable {

private static final String DEFAULT_NAME = "匿名";

private static final int DEFAULT_RECORD = 999;

private int record;

private String user;

public LevelLog() {

setDefault();

}

public void setDefault() {

user = DEFAULT_NAME;

record = DEFAULT_RECORD;

}

public void setRecord(int r) {

record = r;

}

public void setUserName(String name) {

user = name;

}

public int getRecord() {

return record;

}

public String getUserName() {

return user;

}

public String toString() {

return record + "\t" + user + "\n";

}

}

3.3.10 LogDialog类

LogDialog类:扫雷英雄榜,其实现代码如下:

public class LogDialog extends JDialog implements ActionListener {

private LevelLog levelLog[];

private JTextArea logArea;

private JButton resetButton;

private JButton confirmButton;

public LogDialog(JFrame frame, LevelLog log[]) {

super(frame, "扫雷英雄榜", true);

getContentPane().setLayout(null);

levelLog = log;

logArea = new JTextArea();

logArea.setEditable(false);

logArea.setBackground(UIManager.getColor("CheckBox.background"));

logArea.setBounds(10,10,160,60);

getContentPane().add(logArea, null);

resetButton = new JButton("重新计分");

resetButton.setBounds(10,70,90,25);

resetButton.addActionListener(this);

getContentPane().add(resetButton, null);

setTextArea();

confirmButton = new JButton("确定");

confirmButton.setBounds(105,70,60,25);

confirmButton.addActionListener(this);

getContentPane().add(confirmButton, null);

setSize(180,140);

setLocationRelativeTo(frame);

setResizable(false);

show();

}

private void setTextArea() {

logArea.setText("初级:" + levelLog[0].toString()

+ "中级:" + levelLog[1].toString()

+ "高级:" + levelLog[2].toString());

}

public void actionPerformed(ActionEvent e) {

if(e.getSource()==resetButton) {

for(int i=0;i<3;i++) {

levelLog[i].setDefault();

}

setTextArea();

} else {

dispose();

}

}

}

相关主题
相关文档
最新文档