基于JAVA的面向对象扫雷源代码(陈立)
- 格式:doc
- 大小:63.00 KB
- 文档页数:8
Java程序课程设计任务书1.设计内容及要求1.1 扫雷游戏的基本要求Windows 2000/XP系统提供的扫雷游戏是一个很有趣的游戏。
本章的课程设计使用Java 语言编写一个与其类似的扫雷游戏。
具体要求如下:(1)选择级别后将出现相应级别的扫雷区域,这是用户使用鼠标左键单击雷区中任何一个方块便启动计时器.(2)用户要揭开某个方块,可单击它。
若所揭方块下有雷,用户便输了这一局,若所揭方块下五雷,则显示一个数字,该数字代表方块的周围的8个方块中共有多少颗雷。
(3) 如果用户认为某个方块下埋着雷,单击右键可以在方块上标识一个用户认为是雷的图标,即给出一个扫雷标记。
用户每标记出一个扫雷标记(无论用户的标记是否正确),程序将显示的剩余雷数减少一个。
(4)扫雷胜利后,显示游戏胜利。
(5) 用户可以右击空格,可以选择标记为“旗帜”、“问号”或者返回成空格。
计划进度1.12月28日-- 12 月28日:搜集资料、查阅文献,确定选题2.12月29日-- 12月29日:需求分析,系统设计,系统功能模块完善3.12月30日——1月1日:编程实现系统、系统测试与修改4.1月2日—— 1月3日:课程设计报告撰写5.1月7日-- 1月7日:课程设计报告答辩任务分工1。
2 需实现的主要功能(1)用户点击笑脸实现复位操作。
调用repaint()和validate()函数对界面进行重置以及刷新操作(2)可以显示用户完全扫雷成功所花时间。
文本框TF记录扫雷成功所花的时间(3)在失败和胜利后跳出失败或胜利的文本框JoptionPane 该类用来调出对话框并提示胜利2.需求分析2.1 扫雷棋盘的布局设计系统的整体布局为:CardLayout布局,采用了文本框、按钮、面板、框架…等组件,菜单主要有run按钮笑脸和哭脸,按钮的功能是重新开始新的游戏。
2.2 雷区的设计MineArea类是javax.swing包中Jpanel容器的子类,实现了ActionListener和MouseListener接口,所创建的对象:mineArea是MineGame类中最重要的成员之一,作为一个容器添加到MineGame窗口的中心。
/*** This program is written by Jerry Shen(Shen Ji Feng)* use the technology of SWING GUI and the OO design** @author Jerry Shen(jerry.shen@)* Distributed under the licience of GPLv3* all rights reserved.*/import java.awt.*;import javax.swing.*;//图形计数器JCounter三位class JCounter extends JPanel {private ImageIcon [] numSet = { new ImageIcon("c0.gif"), new ImageIcon("c1.gif"),new ImageIcon("c2.gif"), new ImageIcon("c3.gif"),new ImageIcon("c4.gif"), new ImageIcon("c5.gif"),new ImageIcon("c6.gif"), new ImageIcon("c7.gif"),new ImageIcon("c8.gif"), new ImageIcon("c9.gif"),};private JButton [] counter = { new JButton(numSet[0]), new JButton(numSet[0]), new JButton(numSet[0])};private int counterNum;private Insets space;public JCounter() {this(0);}public JCounter(int num) {super();setSize(23, 39);space = new Insets(0,0,0,0);this.counterNum = num;for (int i=0; i< 3; i++){counter[i].setSize(13,23);counter[i].setMargin(space);add(counter[i]);}this.setVisible(true);resetImage();}public int getCounterNum() {return(counterNum);}private void setCounterNum(int num){this.counterNum = num;}private void resetImage() {int ones, tens, hundreds;ones = counterNum % 10 ;tens = counterNum % 100/10;hundreds = (counterNum) % 1000/100;this.counter[0].setIcon(numSet[hundreds]);this.counter[1].setIcon(numSet[tens]);this.counter[2].setIcon(numSet[ones]);}public void resetCounter(int num) {setCounterNum(num);resetImage();this.repaint();}public static void main(String[] args) {JFrame jf = new JFrame("Test");jf.setSize(23,39);JCounter jc = new JCounter();jf.setContentPane(jc);jf.show();jc.resetCounter(394);}}。
JAVA扫雷游戏开发文档一、程序思想扫雷是一款相当经典的小游戏,下面是我们的扫雷程序思想。
我们可以把整个雷区看成一个二维数组.首先我们在雷区上随机地放上雷,这可以用random类来实现。
当没有雷的地方被点击后就会显示一个数字表示它周围有几个雷,要实现这个功能,,如雷区a[i][j]:a[1][1] a[1][2] a[1][3] a[1][4] a[1][5] a[1][6] a[1][7] a[1][8] a[2][1] a[2][2] a[2][3] a[2][4] a[2][5] a[2][6] a[2][7] a[2][8] a[3][1] a[3][2] a[3][3] a[3][4] a[3][5] a[3][6] a[3][7] a[3][8] a[4][1] a[4][2] a[4][3] a[4][4] a[4][5] a[4][6] a[4][7] a[4][8] a[5][1] a[5][2] a[5][3] a[5][4] a[5][5] a[5][6] a[5][7] a[5][8] 我们可以发现a[i][j]周围存在着如下关系:a[i-1][j-1] a[i-1][j] a[i-1][j+1]a[i][j-1] a[i][j] a[i][j+1]a[i+1][j-1] a[i+1][j] a[i+1][j+1]于是,可以从a[i][j]的左上角顺时针开始检测。
当然,如果超出边界,要用约束条件再加以判断!扫雷程序还会自动展开已确定没有雷的雷区。
如果a[3][4]周围雷数为1,a[2][3]已被标示为地雷,那么a[2][4],a[2][5],a[3][3],a[3][5],a[4][3],a[4][4],a[4][5]将被展开,一直波及到不可确定的雷区。
这也是实现的关键!我们可以把数组的元素设定为一个类对象(类中定义:第几号方块,周围雷数,是否为雷,是否被点击,探雷标记,是否点击右键),它们所属的类设定这样的一个事件:在被展开时,检查周围的雷数是否与周围标示出来的雷数相等,如果相等则展开周围未标示的雷区。
教你怎么⽤Java开发扫雷游戏⽬录⼀、效果图⼆、实现思路三、代码实现3.1 设置头部3.2 设置游戏区域按钮3.3 设置雷3.4 计算周围雷的数量并显⽰3.5 添加点击事件3.6 打开指定按钮3.7 触雷爆炸3.8 递归打开周围3.9 ⿏标右键事件四、胜利判定⼀、效果图⼆、实现思路1.界⾯上可以点开的各种实际都是按钮,创建9⾏9列的⼆维数组,然后根据这个数组来创建JButton。
2.对应创建⼆维数组data,⽤来存取数据,0表⽰周围⽆雷,-1表⽰当前是雷,其他数字表⽰周围雷的数量。
3.对应创建⼆维数组state,⽤来存取按钮状态,0未打开,1 打开 2旗⼦ 3 未知(控制显⽰对应的图标)4.设置雷:随机⾏数 i 和列数 j,根据随机到 i、j 从⼆维数组data中取出对应的元素值,若值不为-1(不是雷),则将此元素data[i][j]设置为-1,若值是-1(已经是雷了),则跳过,不管是否跳过都进⾏递归,直到雷的数量达到设定的最⼤数量,跳出递归。
5.设置周围雷的数量:计算每个元素周围的雷数量(周围指的是左上、上、右上、右、右下、下、左下、左这8个位置),循环⼆维数组data,判断当前值不是-1,则需要计算周围雷的数量,等会细说。
6.有任⼀格⼦被揭开,则游戏开始并且计时,当格⼦被揭开的时候分3种情况(1)格⼦是雷,执⾏爆炸动画,游戏结束。
(2)当前格⼦周围有雷,则仅仅打开此格⼦,对应显⽰周围雷数量的数字图⽚。
(3)当前格⼦不是雷且周围没有雷(data取到的元素值为0),则依次打开周围,并且被打开的周围元素也没有雷的情况下,继续打开(递归)。
7.右键可以进⾏插⼩旗、打问号等操作(对数组state进⾏的操作)。
三、代码实现3.1 设置头部//设置头部private void setHeader() {Container container = new Container();container.setLayout(new GridLayout(1, 3));timeJLabel = new JLabel("时间:"+time,JLabel.CENTER);timeJLabel.setForeground(Color.DARK_GRAY);timeJLabel.setFont(new Font("微软雅⿊",Font.BOLD, 16));leiJLabel = new JLabel("雷:"+curLeiCount,JLabel.CENTER);leiJLabel.setForeground(Color.DARK_GRAY);leiJLabel.setFont(new Font("微软雅⿊",Font.BOLD, 16));reStart = new JButton((ImageIcon)imageMap.get(21));Dimension preferredSize = new Dimension(100,40);reStart.setPreferredSize(preferredSize);reStart.addActionListener(this);//注意添加顺序container.add(timeJLabel);container.add(reStart);container.add(leiJLabel);mainFrame.add(container,BorderLayout.NORTH);}3.2 设置游戏区域按钮1.创建容器,并采⽤GridLayout 布局。
JAVA程序设计A课程设计题目基于JA V A的扫雷游戏的设计与实现院(系)信息工程学院专业班级计算机科学与技术(2)班学生姓名学号设计地点教(13)软件实验室指导教师起止时间:2014年6月9日至2014年6月13日《Java程序设计A》课程设计任务分工及成绩院(系):信息工程学院教研室:软件教研室课程设计题目基于JA V A的扫雷游戏的设计与实现课程设计内容用JAVA实现扫雷游戏,了解扫雷游戏的基本结构,和理解扫雷的算法,并努力对算法进行改进,调试过程中修复程序中的bugg,使该扫雷游戏尽可能完善。
设计内容:1、扫雷游戏分为初级、中级和高级三个级别。
单击游戏菜单可以选择“初级”、“中级”和“高级”。
2、选择级别后将出现相应级别的扫雷区域,这时用户使用鼠标左键单击‘“开始”便启动计时器。
3、用户要揭开某个方块,可左键单击它。
若所揭方块下有雷,用户便输了这一局,若所揭方块下无雷,则显示一个数字,该数字代表方块的周围的8个方块中共有多少颗雷。
4、如果用户认为某个方块下埋着雷,单击右键可以在方块上标识一个用户认为是雷的图标,即给出一个扫雷标记。
用户每标记出一个扫雷标记(无论用户的标记是否正确),程序将显示的剩余雷数减少一个。
小组成员及任务分配姓名学号承担任务成绩算法实现游戏布局设置监听器基于JAVA的扫雷游戏的设计与实现摘要随着时代的发展,电脑进入了普通老百姓的生活,越来越多的人使用电脑办公、娱乐、上网,游戏行业发展一日千里,该行业极大的影响和改变了人们的生活和娱乐方式,游戏为消费者提供丰富多彩的虚拟空间,使消费者可以自由自在的享受虚拟世界的乐趣,实现自己在现实生活着那个可能永远不能实现的梦想,满足了消费者的心理和精神需求。
扫雷游戏是Windows 操作系统自带的一款小游戏,本系统要是模仿WINDOWS 系统的扫雷,对于实现过程中出现的 bug 进行调试解决。
我这里用的是 C#编写了与它功能相似的扫雷游戏。
扫雷不能不说一款非常经典的游戏,无聊时候可以打发时间,虽然玩了很久,但还不知道它是怎么写的,所以自己就尝试动手做了个。
众所周知,java的swing采用mvc模式,即模型-视图-控制器,所以如果真的了解了这个模式,较c++,用java做个游戏还是比较容易的。
下面是我写的扫雷的代码import java.awt.*;import java.io.*;import .URL;import java.awt.geom.*;import java.awt.event.*;import javax.swing.*;import java.util.ArrayDeque;import java.util.ArrayList;import java.util.concurrent.*;public class MineSweep{public static void main(String[] args){JFrame frame = new MineFrame();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}}class MineFrame extends JFrame{private JPanel buttonPanel;private MinePanel mp;private int rn,cn;public static final int DEFAULT_WIDTH = 650; public static final int DEFAULT_HEIGHT = 450; public static final int DEFAULT_CN = 9;public static final int DEFAULT_RN = 9;public JLabel remainMine;public JLabel mes;private JComboBox cb;public MineFrame(){setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);setTitle("扫雷");mp = new MinePanel(DEFAULT_CN,DEFAULT_RN,this); mp.setMinenum(10);mp.setRC(9,9);buttonPanel = new JPanel();add(mp,BorderLayout.CENTER);mes = new JLabel("");mes.setEnabled(false);add(mes,BorderLayout.EAST);cb = new JComboBox();cb.setEditable(true);cb.addItem("初级");cb.addItem("中级");cb.addItem("高级");cb.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {int index = cb.getSelectedIndex(); System.out.println(index);switch(index){case 0:mp.setMinenum(10);mp.setRC(9,9);break;case 1:mp.setMinenum(40);mp.setRC(16,16);break;case 2:mp.setMinenum(99);mp.setRC(30,16);break;}}});JButton showAll = new JButton("显示所有地雷");showAll.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e){mp.showMines();}});buttonPanel.add(showAll);JButton replay = new JButton("重新开始");replay.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e){mp.updateMines();}});buttonPanel.add(replay);buttonPanel.add(cb);remainMine = new JLabel("剩余雷数:" +mp.getMinenum()); add(remainMine,BorderLayout.SOUTH);add(buttonPanel,BorderLayout.NORTH);}}class Pair{public Pair(int r,int c){this.r = r;this.c =c;}public int r;public int c;}class MinePanel extends JPanel implements MouseListener {private int cn,rn;private int minenum;private Mine[][] mines;private int hideMine = minenum;private int ableMn ;private MineFrame f;private boolean over ;private int w,h;private boolean win;public static ArrayList<Image> IMAGES = new ArrayList<Image>(12); public MinePanel(int rn,int cn,MineFrame f){IMAGES.add(new ImageIcon(getURL(".\\img\\0.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\1.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\2.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\3.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\4.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\5.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\6.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\7.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\8.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\mine.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\11.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\12.gif")).getImage()); this.f = f;this.rn = rn; = cn;this.ableMn = rn * cn;addMouseListener(this);updateMines();}public URL getURL(String file){URL url =null;try{url = this.getClass().getResource(file); }catch(Exception e){e.printStackTrace();}return url;}public void decAbleMn(){ableMn --;}public int getAbleMn(){return ableMn;}public void decHideMine(){hideMine --;}public void incHideMine(){hideMine ++;}public int getHideMine(){return hideMine;}public void setMinenum(int n){minenum = n;}public int getMinenum(){return minenum;}public void mousePressed(MouseEvent e) {if(!over){int x = (int)e.getX();int y = (int)e.getY();int keyCode = e.getButton();int c,r;r = x/Mine.WIDTH;c = y/Mine.HEIGHT;switch(keyCode){case MouseEvent.BUTTON1:if(mines[r][c].getFlag() == false) {try{mines[r][c].setOpen();decAbleMn();if(mines[r][c].getImage() == 9){over = true;decHideMine();showMines();}else if(mines[r][c].getImage() == 0) {if(getAbleMn() == rn * cn - minenum) {win = true;}openNear(r,c);}}catch(Exception ex){//e.printStackTrace();}repaint();}break;case MouseEvent.BUTTON3:if( mines[r][c].isOpen() == false || mines[r][c].getFlag() == true) {if(mines[r][c].getFlag() == true){incHideMine();mines[r][c].setFlag();repaint();}else if(hideMine > 0){mines[r][c].setFlag();decHideMine();repaint();}}break;}}}public void mouseReleased(MouseEvent e){}public void mouseClicked(MouseEvent e){}public void mouseEntered(MouseEvent e){}public void mouseExited(MouseEvent e){}private ArrayDeque<Pair> queue = new ArrayDeque<Pair>(20); public void openNear(int r,int c){int i,j;i = r;j = c;for(int n = -1; n <= 1; n ++){r = i + n;if(r >= 0 && r <mines.length)for(int k = -1; k <=1; k ++){c = j + k;if(c >= 0 && c < mines[r].length){if(mines[r][c].isOpen() == false && mines[r][c].getImage() == 0) {mines[r][c].setOpen();queue.add(new Pair(r,c));}else{if(mines[r][c].getFlag() ==true){mines[r][c].setFlag();incHideMine();}mines[r][c].setOpen();}}}}for(i = 0 ;i < queue.size(); i ++){Pair p = queue.poll();openNear(p.r,p.c);}}public void setRC(int rn,int cn){this.rn = rn; = cn;updateMines();repaint();}public void updateMines(){removeAll();win = false;over = false;f.setSize((10 +rn) * 20,(cn + 10) * 20);setSize(rn * Mine.HEIGHT,cn * Mine.WIDTH);mines = new Mine[rn][cn];for(int i = 0;i < mines.length;i ++)for(int j = 0 ;j < mines[i].length; j ++){mines[i][j] = new Mine(i,j);}int mn = getMinenum();hideMine = mn;for(int i = 0; i <mn;i ++){int r,c;do{r = (int)(Math.random() * rn);c = (int)(Math.random() * cn);}while(mines[r][c].getImage() == 9); mines[r][c].setImage(9);}generateNum();repaint();}public void generateNum(){int r,c;for(int i = 0 ;i < mines.length;i ++)for(int j = 0 ;j < mines[i].length; j ++) if(mines[i][j].getImage() != 9){int cnum = 0 ;for(int n = -1; n <= 1; n ++){r = i + n;if(r >= 0 && r < mines.length)for(int k = -1 ;k <=1; k ++){c = j + k;if(c >= 0 && c < mines[i].length){if(mines[r][c].getImage() == 9)cnum ++;}}}mines[i][j].setImage(cnum);}}public void paintComponent(Graphics g) {super.paintComponent(g);int c = 0;Graphics2D g2 = (Graphics2D) g;for(int i = 0 ;i < mines.length; i ++)for(int j = 0 ;j < mines[i].length; j ++){g2.setColor(mines[i][j].getColor());g2.draw(mines[i][j].getShape());if(mines[i][j].getFlag() == true && mines[i][j].isOpen() == false)g.drawImage(IMAGES.get(10),mines[i][j].getW(),mines[i][j].getH(),Mine .HEIGHT,Mine.WIDTH,this);if(mines[i][j].isOpen()&& mines[i][j].getFlag() == false ){g.drawImage(IMAGES.get(mines[i][j].getImage()),mines[i][j].getW(),min es[i][j].getH() ,Mine.HEIGHT,Mine.WIDTH,this);c ++;}}f.remainMine.setText("剩余雷数:" + getHideMine() );}public void showMines(){removeAll();for(int i = 0 ;i <mines.length; i ++)for(int j = 0 ; j < mines[i].length; j ++){if(mines[i][j].getImage() == 9){if(mines[i][j].getFlag() == false)mines[i][j].setOpen();}else{if(mines[i][j].getFlag() == true){mines[i][j].setOpen();mines[i][j].setFlag();mines[i][j].setImage(11);}}}hideMine = 0;repaint();}}class Mine{private Rectangle2D rect = null;public static final ImageIcon IMAGE = new ImageIcon("mine.gif");public static final int HEIGHT = 20;public static final int WIDTH = 20;private boolean flag = false;private boolean open = false;public static final Color DEFAULT_COLOR = Color.BLACK;private int image = 0;private Color color;private boolean isMine = false;private int w,h;public Mine(int r,int c){this.w = r * HEIGHT;this.h = c * HEIGHT;rect = new Rectangle2D.Double(1.0D *r * HEIGHT,1.0D *c * WIDTH ,1.0D *HEIGHT,1.0D *WIDTH);setColor(DEFAULT_COLOR);}public void setMine(){isMine = true;}public boolean isMine(){return isMine;}public void setColor(Color c)this.color = c;}public Color getColor() {return color;}public void setOpen(){open = true;}public boolean isOpen() {return open;}public void setImage(int n) {image =n;}public int getImage(){return image;}public int getW()return w;}public int getH(){return h;}public void setFlag(){flag = !flag;}public boolean getFlag(){return flag;}public Shape getShape(){return rect;}}代码主要包含三个类,MineSweep,MinePanel和Mine类。
JAVA实现经典扫雷游戏的⽰例代码⽬录前⾔主要设计功能截图代码实现总结前⾔windows⾃带的游戏《扫雷》是陪伴了⽆数⼈的经典游戏,本程序参考《扫雷》的规则进⾏了简化,⽤java语⾔实现,采⽤了swing技术进⾏了界⾯化处理,设计思路⽤了⾯向对象思想。
主要需求1、要有难度等级,初级,中级,⾼级2、由玩家逐个翻开⽅块,以找出所有地雷为最终游戏⽬标。
如果玩家翻开的⽅块有地雷,则游戏结束3、游戏主区域由很多个⽅格组成。
使⽤⿏标左键随机点击⼀个⽅格,⽅格即被打开并显⽰出⽅格中的数字;⽅格中数字则表⽰其周围的8个⽅格隐藏了⼏颗雷。
4、⽤户右键可标记雷的位置5、雷都被标记出来则胜利主要设计1、格⼦格数固定为10*10格2、难度等级,初级:12,中级:24,⾼级:363、点击格⼦时,产⽣没有引爆的地图效果;4、点击格⼦时,此格⼦是雷,则显⽰所有雷的位置,并递归清空⾮雷格⼦,结束游戏5、实现检查所有的雷是否都被标记出来了,如果是,则胜利算法。
6、实现计时器算法,⽤来计时显⽰游戏开始多少秒7、实现难度等级,雷数的显⽰8、实现⿏标左键的实现逻辑9、实现⿏标右键的标记逻辑功能截图开始界⾯左键选中格⼦效果左键选中雷效果右键标记雷效果胜利效果代码实现程序启动类public class JMine extends JFrame implements MouseListener, ActionListener {private JMineArth mine;private JMineButton[][] mineButton;private GridBagConstraints constraints;private JPanel pane;private GridBagLayout gridbag;private boolean gameStarted;private static JCounter mineCounter;private static JCounter timeCounter;private Timer timer;private Timer winTimer = new Timer();public int numMine;public int numFlaged;private JMenuBar mb;private JMenu mGame;private JMenuItem miEasy;private JMenuItem miMiddle;private JMenuItem miHard;private JMenuItem miExit;private JMenu mHelp;private JMenuItem miAbout;private JPanel controlPane;private JButton bTest;private AboutFrame about;private WinFrame winFrame;private ImageIcon[] mineNumIcon = { new ImageIcon(JMine.class.getClassLoader().getResource("blank1.gif")),new ImageIcon(JMine.class.getClassLoader().getResource("1.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("2.gif")),new ImageIcon(JMine.class.getClassLoader().getResource("3.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("4.gif")),new ImageIcon(JMine.class.getClassLoader().getResource("5.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("6.gif")),new ImageIcon(JMine.class.getClassLoader().getResource("7.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("8.gif")),new ImageIcon(JMine.class.getClassLoader().getResource("0.gif"))};private ImageIcon[] mineStatus = { new ImageIcon(JMine.class.getClassLoader().getResource("blank1.gif")),new ImageIcon(JMine.class.getClassLoader().getResource("flag.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("question.gif")) }; private ImageIcon[] mineBombStatus = { new ImageIcon(JMine.class.getClassLoader().getResource("0.gif")),new ImageIcon(JMine.class.getClassLoader().getResource("mine.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("wrongmine.gif")), new ImageIcon(JMine.class.getClassLoader().getResource("bomb.gif")) };private ImageIcon[] faceIcon = { new ImageIcon(JMine.class.getClassLoader().getResource("smile.gif")),new ImageIcon(JMine.class.getClassLoader().getResource("Ooo.gif")) };// You loseprivate void bomb(int row, int col){try{//System.out.println("Bomb!");for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {mineButton[i][j].setIcon(mineBombStatus[0]);int toShow;toShow = mine.mine[i][j] != 9 ? 0 : 1;mineButton[i][j].setClickFlag(true);if (toShow == 1 && (i != row || j != col)) {mineButton[i][j].setIcon(mineBombStatus[toShow]);mineButton[i][j].setClickFlag(true);} else if (toShow == 1 && (i == row && j == col)) {mineButton[i][j].setIcon(mineBombStatus[3]);mineButton[i][j].setClickFlag(true);} else if (toShow == 0 && mineButton[i][j].getFlag() != 1) { mineButton[i][j].setEnabled(false);} else if (toShow == 0 && mineButton[i][j].getFlag() == 1) { mineButton[i][j].setIcon(mineBombStatus[2]);mineButton[i][j].setClickFlag(true);}}}timer.cancel();}catch (Exception e){}}// check if you win() {private boolean isWin() {for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {if (mine.mine[i][j] == 9 && mineButton[i][j].getFlag() != 1) { return (false);}if (mine.mine[i][j] != 9 && mineButton[i][j].getFlag() == 1) { return (false);}if (mine.mine[i][j] != 9&& mineButton[i][j].getClickFlag() == false) {return (false);}}}return (true);}// You Winprivate void win(){timer.cancel();winFrame.setVisible(true);winTimer.schedule(new TimerTask(){public void run() {while(!winFrame.getWinOk()){}numMine = winFrame.getMineNum();winFrame.setVisible(false);setNewGame(numMine);//System.out.println("Jerry Debug:"+numMine);this.cancel();winFrame.setWinOk(false);}},0L);}// Constructor of the gamepublic JMine() {super("JMine Game");setSize(250, 350);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);Insets space = new Insets(0, 0, 0, 0);// Game varsgameStarted = false;numMine = 12;numFlaged = 0;ImageIcon myIcon = new ImageIcon(JMine.class.getClassLoader().getResource("blank1.gif")); gridbag = new GridBagLayout();constraints = new GridBagConstraints();pane = new JPanel();pane.setLayout(gridbag);constraints.fill = GridBagConstraints.BOTH;constraints.anchor = GridBagConstraints.CENTER;// Begin Menu Setmb = new JMenuBar();mGame = new JMenu("Game");miEasy = new JMenuItem("Easy");miEasy.addActionListener(this);miMiddle = new JMenuItem("Middle");miMiddle.addActionListener(this);miHard = new JMenuItem("Hard");miHard.addActionListener(this);miExit = new JMenuItem("Exit");miExit.addActionListener(this);mGame.add(miEasy);mGame.add(miMiddle);mGame.add(miHard);mGame.addSeparator();mGame.add(miExit);mb.add(mGame);mHelp = new JMenu("Help");miAbout = new JMenuItem("About...");mHelp.add(miAbout);miAbout.addActionListener(this);mb.add(mHelp);this.setJMenuBar(mb);// end of Menu Set// Control PanelcontrolPane = new JPanel();bTest = new JButton(faceIcon[0]);bTest.setSize(26, 27);bTest.setMargin(space);bTest.addMouseListener(this);bTest.setPressedIcon(faceIcon[1]);mineCounter = new JCounter(numMine);timeCounter = new JCounter();controlPane.add(mineCounter);controlPane.add(bTest);controlPane.add(timeCounter);buildConstraints(constraints, 0, 0, 10, 2, 100, 100);gridbag.setConstraints(controlPane, constraints);pane.add(controlPane);// BottonsmineButton = new JMineButton[10][10];for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {mineButton[i][j] = new JMineButton(i, j, myIcon);mineButton[i][j].addMouseListener(this);mineButton[i][j].setMargin(space);buildConstraints(constraints, j, i + 3, 1, 1, 100, 100);gridbag.setConstraints(mineButton[i][j], constraints);pane.add(mineButton[i][j]);}}// Content PanesetContentPane(pane);setLocation(200, 150);setVisible(true);// About Frameabout = new AboutFrame("JMine About");winFrame = new WinFrame("You win!");}// Set the GUI objects positionsvoid buildConstraints(GridBagConstraints gbc, int gx, int gy, int gw, int gh, int wx, int wy) {gbc.gridx = gx;gbc.gridy = gy;gbc.gridwidth = gw;gbc.gridheight = gh;gbc.weightx = wx;gbc.weighty = wy;}// the methods to check if there were mines, to be nestedvoid checkMine(int row, int col){int i, j;i = row < 0 ? 0 : row;i = i > 9 ? 9 : i;j = col < 0 ? 0 : col;j = j > 9 ? 9 : j;//System.out.println("Check Mine row:"+i + ",col:" +j);if (mine.mine[i][j] == 9) {bomb(i, j);} else if (mine.mine[i][j] == 0&& mineButton[i][j].getClickFlag() == false) {mineButton[i][j].setClickFlag(true);showLabel(i, j);for (int ii = i - 1; ii <= i + 1; ii++)for (int jj = j - 1; jj <= j + 1; jj++)checkMine(ii, jj);} else {showLabel(i, j);mineButton[i][j].setClickFlag(true);}if (isWin()) {win();}}private void clearAll(int row, int col){int top, bottom, left, right;top = row - 1 > 0 ? row - 1 : 0;bottom = row + 1 < 10 ? row + 1 : 9;left = col - 1 > 0 ? col - 1 : 0;right = col + 1 < 10 ? col + 1 : 9;for (int i = top; i <= bottom; i++) {for (int j = left; j <= right; j++) {if (mineButton[i][j].getFlag() != 1)checkMine(i, j);}}}private void resetAll() {for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {mineButton[i][j].setFlag(0);mineButton[i][j].setClickFlag(false);mineButton[i][j].setIcon(mineStatus[0]);mineButton[i][j].setEnabled(true);mineButton[i][j].setVisible(true);}}}// to flag the mine you want to flag outvoid flagMine(int row, int col) {//System.out.println("Jerry Arrives here!");int i, j;i = row < 0 ? 0 : row;i = i > 9 ? 9 : i;j = col < 0 ? 0 : col;j = j > 9 ? 9 : j;if (mineButton[i][j].getFlag() == 0) {numFlaged++;} else if (mineButton[i][j].getFlag() == 1) {numFlaged--;}mineCounter.resetCounter(numMine - numFlaged >= 0 ? numMine - numFlaged: 0);mineButton[i][j].setFlag((mineButton[i][j].getFlag() + 1) % 3);showFlag(i, j);if (isWin()) {win();}}// show the numbers of the nearby minesvoid showLabel(int row, int col) {//System.out.println("ShowLabel row:" + row + ",col:" + col);int toShow;toShow = mine.mine[row][col];if (toShow != 0) {mineButton[row][col].setIcon(mineNumIcon[toShow]);mineButton[row][col].setClickFlag(true);//mineButton[row][col].setEnabled(false);} else {//mineButton[row][col].setIcon(mineNumIcon[0]);//mineButton[row][col].setClickFlag(true);mineButton[row][col].setEnabled(false);}}// circle the flag with blank, flaged, questionedvoid showFlag(int row, int col) {mineButton[row][col].setIcon(mineStatus[mineButton[row][col].getFlag()]);}// the mouse events listener methodspublic void mouseEntered(MouseEvent e) {//System.out.println("Jerry Test");}// method to start the new gameprivate void startNewGame(int num, int row, int col){mine = new JMineArth(num, row, col);//mine.printMine();gameStarted = true;timer = new Timer();timer.scheduleAtFixedRate(new TimerTask(){public void run() {timeCounter.counterAdd();//System.out.println(timeCounter.getCounterNum());}},1000,1000);}public void setNewGame(int num) {resetAll();numMine = num;numFlaged = 0;gameStarted = false;mineCounter.resetCounter(numMine);timeCounter.resetCounter(0);}// the event handle to deal with the mouse clickpublic void mouseClicked(MouseEvent e) {if (e.getSource() == bTest) {setNewGame(numMine);return;}int row, col;row = ((JMineButton) e.getSource()).getRow();col = ((JMineButton) e.getSource()).getCol();if (!gameStarted) {startNewGame(numMine, row, col);}if (e.getModifiers() == (InputEvent.BUTTON1_MASK + InputEvent.BUTTON3_MASK)) { //System.out.println("HA");clearAll(row, col);}if (!mineButton[row][col].getClickFlag()) {if (e.getModifiers() == InputEvent.BUTTON1_MASK) {//System.out.println("LeftButton");if (mineButton[row][col].getFlag() == 1) {return;} else {checkMine(row, col);}} else if (e.getModifiers() == InputEvent.BUTTON3_MASK) { //System.out.println("RightButton");flagMine(row, col);} else {//System.out.println("MiddleButton");}}}public void mousePressed(MouseEvent e) {//System.out.println("Jerry Press");}public void mouseReleased(MouseEvent e) {//System.out.println("Jerry Release");}public void mouseExited(MouseEvent e) {//System.out.println("Jerry Exited");}public void actionPerformed(ActionEvent e) {try {if (e.getSource() == miEasy) {setNewGame(12);return;}if (e.getSource() == miMiddle) {setNewGame(24);return;}if (e.getSource() == miHard) {setNewGame(36);return;}if (e.getSource() == miExit) {System.exit(0);}if (e.getSource() == miAbout) {about.setVisible(true);}} catch (Exception ie) {}}public static void main(String [] args) {JMine jmine = new JMine();jmine.setVisible(true);}}地雷分布图算法类public class JMineArth {public int [][] mine;private boolean fMineSet;JMineArth(int mineNum, int row, int col) {mine = new int[10][10];setMine(mineNum, row, col);setMineNum();}private void setMine(int mineNum, int Outrow, int Outcol) {int col=0, row = 0, i=0;//Math.srand(now);while (i < mineNum) {col = (int)(Math.random()*100)%10;row = (int)(Math.random()*100)%10;if (mine[col][row]==0 && (row!=Outrow || col!=Outcol || Outrow==10 )) {mine[row][col]=9;i++;}}}private void setMineNum() {for ( int i=0 ; i <10; i++) {for (int j=0; j < 10; j++) {mine[i][j]=mine[i][j]==9?9:checkMineNum(i,j);}}fMineSet = true;}private int checkMineNum(int ii,int jj) {int top,bottom, left, right, count=0;top=ii-1>0?ii-1:0;bottom=ii+1<10?ii+1:9;left=jj-1>0?jj-1:0;right=jj+1<10?jj+1:9;for (int i=top; i<=bottom; i++) {for(int j=left; j<= right; j++) {if (mine[i][j]==9) count++;}}return(count);}public void printMine() {for (int i = 0; i < 10; i++) {for (int j=0; j < 10; j++) {System.out.print(this.mine[i][j] + " ");}System.out.println();}}public static void main(String[] args) {JMineArth mine = new JMineArth(Integer.parseInt(args[0]),Integer.parseInt(args[1]),Integer.parseInt(args[2]));mine.printMine();}}总结通过此次的《扫雷》游戏实现,让我对swing的相关知识有了进⼀步的了解,对java这门语⾔也有了⽐以前更深刻的认识。
Java语⾔实现扫雷游戏(1)Java类库中提供了⽤于GUI的swing开发⼯具包,我们可以利⽤swing设计出⼀些简单的经典⼩游戏,如扫雷,推箱⼦,俄罗斯⽅块等.接下来我就简单分享⼀下⽤Java设计扫雷游戏的思路与过程.⾸先,我们要设计出扫雷的窗⼝界⾯,说⽩了,也就是在窗⼝上绘制出指定⾏数和列数的⼩⽅格.要在窗体上绘制⽅格,我们需要⼀个JPanel⾯板,所以我们定义类GamePanel让它继承⾃JPanel,然后我们在就可以这个类上绘制我们所要的信息了.然后,在类中,我们定义⼀些基本的变量,如⾏数,列数,雷的数量等等,⽅便后⾯使⽤import java.awt.Color;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.BorderFactory;import javax.swing.JLabel;import javax.swing.JPanel;public class GamePanel extends JPanel {private static final long serialVersionUID = 1L;// 界⾯⾏数private int rows;// 界⾯列数private int cols;// 炸弹数private int bombCount;// 每个⽅格宽度private final int BLOCKWIDTH = 20;// 每个⽅格长度private final int BLOCKHEIGHT = 20;// 存储界⾯中每⼀个⽅格的绘制信息private JLabel[][] labels;}(JLabel标签⽤于短⽂本字符串或图像或⼆者的显⽰区,我们⽤它来显⽰⽅格边界,数字,或者雷等信息)接下来我们在构造⽅法中初始化这些类变量// 构造⽅法,初始化参数public GamePanel(int rows, int cols) {this.rows = rows;this.cols = cols;this.bombCount = rows * cols / 10;bels = new JLabel[rows][cols];this.setLayout(null);}然后,我们就可以在这个JPanel⾯板上绘制⼩⽅格了.我们先创建⼀个名为initLabels()的⽅法,在这个⽅法中根据⾏数和列数循环产⽣JLabel标签,并将每个标签的边界绘制出来,填充背景并将它们存储到类⼆维数组变量 labels中,这样,我们就得到了⼀个充满⼩⽅格的扫雷窗体// 界⾯初始化,绘制扫雷的边框private void initLabels(){for (int i = 0; i < this.rows; i++) {for (int j = 0; j < this.cols; j++) {JLabel l = new JLabel("", JLabel.CENTER);// 设置每个⼩⽅格的边界l.setBounds(j * BLOCKWIDTH, i * BLOCKHEIGHT, BLOCKWIDTH, BLOCKHEIGHT);// 绘制⽅格边框l.setBorder(BorderFactory.createLineBorder(Color.GRAY));// 设置⽅格为透明,便于我们填充颜⾊l.setOpaque(true);// 背景填充为黄⾊l.setBackground(Color.YELLOW);// 将⽅格加⼊到容器中(即⾯板JPanel)this.add(l);// 将⽅格存到类变量中,⽅便公⽤labels[i][j] = l;}}}然后在构造⽅法中调⽤这个初始化⽅法this.initLabels();// 写在构造⽅法中当我们将这个JPanel⾯板绘制完后,我们还要将它放在⼀个JFrame容器中它才能显⽰出来,这样我们就需要将JPanel的⼤⼩作为参数传出去,⽅便设置容器的⼤⼩,所以我们再定义⼀个public的⽅法,计算宽和⾼,并以数组的形式传递出去//计算宽和⾼,并传给容器public int[] returnSize() {// 因为窗体的菜单栏,边框也要占⽤像素,所以加上20和40修正⼤⼩int[] a = {this.cols * BLOCKWIDTH + 20, this.rows * BLOCKHEIGHT + 40};return a;}最后创建⼀个Game类,在这个类中写程序的主⼊⼝main,进⾏仿真调试import java.awt.Container;import javax.swing.JFrame;public class Game {public static void main(String[] args) {// 创建JFrame对象作为容器JFrame w = new JFrame();// 创建mainPanel对象,初始化⼀个20*30的⽅格窗体GamePanel mainPanel = new GamePanel(20, 30);// 获取JFrame应给设置的宽度和⾼度int[] a = mainPanel.returnSize();// 设置JFame宽和⾼w.setSize(a[0], a[1]);Container c = w.getContentPane();c.add(mainPanel);w.setVisible(true);}}运⾏程序,结果如下这样,我们第⼀阶段的⼯作就完成了.接下来,我们要在上⾯这个图中产⽣bombCount个炸弹,也就是在我们⽣成的labels中随机挑选出bombCount个炸弹,并⽤"*"显⽰出来// 产⽣bombCount个炸弹,并在labels中⽤"*"标注出来private void randomBomb() {for (int i = 0; i < this.bombCount; i++) {// ⽣成⼀个随机数表⽰⾏坐标int rRow = (int) (Math.random() * this.rows);// ⽣成⼀个随机数表⽰列坐标int rCol = (int) (Math.random() * this.cols);// 根据坐标确定JLabel的位置,并显⽰*bels[rRow][rCol].setText("*");// 设置背景颜⾊bels[rRow][rCol].setBackground(Color.DARK_GRAY);// 设置*的颜⾊bels[rRow][rCol].setForeground(Color.RED);}}然后我们在initLabels()⽅法中调⽤randomBomb()这个⽅法,运⾏程序,显⽰如下:⾄此,我们已经完成了扫雷游戏的⼀半程序,只剩下填充按钮和点击按钮后发⽣的逻辑判断了,这些将在中继续分享完整详细代码(已注释好)已经附在下⼀篇博客中,供交流和学习,欢迎查阅更多精彩游戏,请参考专题以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
Click类package android11;public class Click {private boolean isGamePlay;//是否游戏进行中private boolean isGameWin = false;//是否游戏胜利private char[][] mineArray;//雷数组private boolean[][] darkArray;//幕布数组private int SIZE;//大小Click(boolean darkArray[][], char mineArray[][], boolean isGamePlay, int SIZE) {//构造方法this.SIZE = SIZE;this.isGamePlay = isGamePlay;this.mineArray = mineArray;this.darkArray = darkArray;}public boolean isGamePlay() {return isGamePlay;}public void setGamePlay(boolean isGamePlay) {this.isGamePlay = isGamePlay;}public boolean isGameWin() {return isGameWin;}public void setGameWin(boolean isGameWin) {this.isGameWin = isGameWin;}public boolean[][] getDarkArray() {return darkArray;}public void setDarkArray(boolean[][] darkArray) {this.darkArray = darkArray;}public char[][] getMineArray() {return mineArray;}public void setMineArray(char[][] mineArray) {this.mineArray = mineArray;}// 点中空格就把周围空格的状态置为显示。
同时也把空格旁边的数字的状态置为显示public void space(int x, int y) {darkArray[x][y] = false;// 将点中的空格附近联通的空格的状态置为显示for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {if (darkArray[x - 1 + i][y - 1 + j] != false&& mineArray[x - 1 + i][y - 1 + j] == 'O') {space(x - 1 + i, y - 1 + j);}}}// 将空格周围的数字的状态置为显示for (int i = 0; i < SIZE + 2; i++) {for (int j = 0; j < SIZE + 2; j++) {if (darkArray[i][j] == false && mineArray[i][j] == 'O') {out(i, j);}}}}// 空格旁边的8格的状态都置为显示public void out(int x, int y) {for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {darkArray[x - 1 + i][y - 1 + j] = false;}}}// 进行选择判断,public void temp(int x, int y) {if (mineArray[x][y] == 'M') {// 点中雷,游戏结束isGamePlay = false;// 把游戏进行的状态置为falseisGameWin = false;// 把游戏输赢的状态置为false} else if (mineArray[x][y] == 'O') {// 点中空格space(x, y);// 调用space方法} else {// 点中数字darkArray[x][y] = false;// 把点中的格子的状态置为显示}}}Curtain类package android11;public class Curtain {private int SIZE;//大小private boolean isGamePlay;//是否游戏进行中//构造方法Curtain(int SIZE, boolean isGamePlay) {this.SIZE = SIZE;this.isGamePlay = isGamePlay;}//幕布布置方法public boolean[][] dark() {boolean darkArray[][] = new boolean[SIZE + 2][SIZE + 2];for (int i = 0; i < SIZE + 2; i++) {for (int j = 0; j < SIZE + 2; j++) {//如果游戏进行中。
把幕布置为true.否则置为falseif (isGamePlay) {darkArray[i][j] = true;} else {darkArray[i][j] = false;}}}return darkArray;}public int getSIZE() {return SIZE;}public void setSIZE(int SIZE) {this.SIZE = SIZE;}public boolean isGamePlay() {return isGamePlay;}public void setGamePlay(boolean isGamePlay) {this.isGamePlay = isGamePlay;}}Game类package android11;import java.util.Scanner;public class Game {static Scanner input = new Scanner(System.in);public static int SIZE;// 大小public static int kNumber;// 雷数public static boolean isGamePlay = true;// 游戏是否进行public static char[][] mineArray;// 雷数组public static boolean[][] darkArray;// 幕布数组public static void main(String[] args) {System.out.println("请选择难度:");System.out.println("输入1为初级难度:9×9格。
10个雷");System.out.println("输入2为中级难度:12×12格。
25个雷");System.out.println("输入3为高级难度:15×15格。
40个雷");System.out.println("输入4为自定义:");SIZE = input.nextInt();if (SIZE == 1) {// 难度1的面板初始化SIZE = 9;kNumber = 10;} else if (SIZE == 2) {// 难度2的面板初始化SIZE = 12;kNumber = 25;} else if (SIZE == 3) {// 难度3的面板初始化SIZE = 15;kNumber = 40;} else {// 自定义的面板初始化System.out.println("请输入你想要的长度(9-24)");SIZE = input.nextInt();System.out.println("请输入你想要的雷数(10-476)");kNumber = input.nextInt();}Mine mine = new Mine(SIZE, kNumber);// 实例化MinemineArray = mine.mineCollocation();// 用mineArray接受布置好的雷数组Curtain curtain = new Curtain(SIZE, isGamePlay);// 实例化CurtaindarkArray = curtain.dark();// 用darkArray接受布置好的幕布数组Play play = new Play(SIZE, mineArray, darkArray);// 实例化PlayClick click = new Click(darkArray, mineArray, isGamePlay, SIZE);// 实例化Click// 判断条件是挖开了所有非雷还没爆或者isGamePlay为falsefor (int i = 0; i < (SIZE * SIZE - kNumber) && click.isGamePlay(); i++) {play.display();// 调用play类中的display方法,打印输出System.out.println("请输入横纵坐标");// 输入要挖的坐标int x = input.nextInt();int y = input.nextInt();click.temp(x, y);// 调用click中的temp方法play.setDarkArray(click.getDarkArray());// 将play类中的幕布数组更新play.setMineArray(click.getMineArray());// 将play类中的雷数组更新}curtain.setGamePlay(false);// 将curtian类中的isGamePlay置为false// 调用curtain类中的dark方法使得幕布数组全部为falseplay.setDarkArray(curtain.dark());play.display();// 重新打印输出if (click.isGameWin()) {// 根据click类中的isGameWin来判断输赢System.out.println("您赢了");} else {System.out.println("您输了");}}}Mine类package android11;import java.util.Random;public class Mine {private int SIZE;// 大小private int kNumber;// 雷数Random rand = new Random();Mine(int SIZE, int kNumber) {this.SIZE = SIZE;this.kNumber = kNumber;}//布置雷数组。