Java编写的扫雷小程序
- 格式:doc
- 大小:333.50 KB
- 文档页数:14
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扫雷游戏设计报告1·设计内容及要求1.1·扫雷小游戏的基本要求扫雷小游戏主要采用Java语言编写,适合windows XP 以下的系统,以eclipse 为平台。
具体要求如下:<1> 扫雷小游戏分为初级、中级和高级三个级别,扫雷排行榜保存着每个级别的最好成绩,即挖出全部的地雷并且用时最少。
单机游戏菜单选择“初级”、“中级”和“高级”。
<2> 游戏默认的是初级级别,用户可以选择不同级别将出现对应级别的扫雷区域,单击扫雷区域任一方格以便启动计时器。
<3> 用户选择某个方格,单击它就行。
若所选择的放阁下有雷,这一局就结束了,若所选择方格下无雷,则会显示一个数字,该数字代表方格周围8个方格中共有几颗雷。
<4> 如果用户认为某个方格下有雷,单击右键可以在方格上标记一个用户认为是雷的图标(一个小旗子)。
<5> 用户可以选择标记为疑问的方格,可以选择游戏菜单下的标记,或者双击右键所选方格显示(?)图标。
<6> 扫雷完成后,程序弹出保存成绩的对话框,用户可以根据自身选择是否保存。
<7> 如果用户喜欢有提示音,可以选择游戏菜单中的声音选项,单击扫雷区域任一方格,就会听到吧嗒声。
当点中地雷时,将会有爆炸声音响起,胜利后,将播放凯旋的旋律。
1.2 需求实现的主要功能(1)该游戏具有计时功能,即扫完全部地雷所花费的时间。
(2)用户可以选择是否有音效。
(3)用户可以自定义级别,还可以输入任意地雷数。
(4)自动保存扫雷排行榜。
2·需求分析2.1 扫雷区域的布局设计系统的整体布局为:CardLayout 布局,采用菜单、按钮、面板……等组件,菜单项主要有开始,选择级别,自定义,标记,声音,扫雷排行榜,退出,按钮的功能是重新开始游戏(可以选择游戏菜单里的开局,也可以点击企鹅图标重新开始游戏)。
2.2 雷区的设计MineArea类是javax.swing 包中Jpanel容器的子类,实现了ActionListener 和MouseListener接口,所创建的对象:mineArea是MineGame类中最重要的成员之一,作为一个容器添加到MineGame窗口的中心。
教你怎么⽤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的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实现简单扫雷游戏本⽂实例为⼤家分享了java实现简单扫雷游戏的具体代码,供⼤家参考,具体内容如下package com.test.swing;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;/*** 这个是⼀个简单的扫雷例⼦,刚接触swing编写的,适合新⼿练习* 该程序使⽤setBounds(x,y,w,h)对控件布局* 做法参考win xp⾃带的扫雷,当然还写功能没做出来,* 另外做出来的功能有些还存在bug** @author Ping_QC*/public class Test extends JFrame implements ActionListener, Runnable,MouseListener {private static final long serialVersionUID = -2417758397965039613L;private final int EMPTY = 0;private final int MINE = 1;private final int CHECKED = 2;private final int MINE_COUNT = 10; // 雷的个数private final int BUTTON_BORDER = 50; // 每个点的尺⼨private final int MINE_SIZE = 10; // 界⾯规格, 20x20private final int START_X = 20; // 起始位置xprivate final int START_Y = 50; // 起始位置yprivate boolean flag;private JButton[][] jb;private JLabel jl;private JLabel showTime;private int[][] map;/*** 检测某点周围是否有雷,周围点的坐标可由该数组计算得到*/private int[][] mv = { { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 },{ 1, -1 }, { 0, -1 }, { -1, -1 } };/*** 随机产⽣设定个数的雷*/public void makeMine() {int i = 0, tx, ty;for (; i < MINE_COUNT;) {tx = (int) (Math.random() * MINE_SIZE);ty = (int) (Math.random() * MINE_SIZE);if (map[tx][ty] == EMPTY) {map[tx][ty] = MINE;i++; // 不记重复产⽣的雷}}}/*** 将button数组放到frame上,与map[][]数组对应*/public void makeButton() {for (int i = 0; i < MINE_SIZE; i++) {for (int j = 0; j < MINE_SIZE; j++) {jb[i][j] = new JButton();// if (map[i][j] == MINE)// jb[i][j].setText(i+","+j);// listener addjb[i][j].addActionListener(this);jb[i][j].addMouseListener(this);jb[i][j].setName(i + "_" + j); // ⽅便点击是判断是点击了哪个按钮// Font font = new Font(Font.SERIF, Font.BOLD, 10);// jb[i][j].setFont(font);// jb[i][j].setText(i+","+j);jb[i][j].setBounds(j * BUTTON_BORDER + START_X, i* BUTTON_BORDER + START_Y, BUTTON_BORDER, BUTTON_BORDER); this.add(jb[i][j]);}}}public void init() {flag = false;jl.setText("欢迎测试,⼀共有" + MINE_COUNT + "个雷");jl.setVisible(true);jl.setBounds(20, 20, 500, 30);this.add(jl);showTime.setText("已⽤时:0 秒");showTime.setBounds(400, 20, 100, 30);this.add(showTime);makeMine();makeButton();this.setSize(550, 600);this.setLocation(700, 100);this.setResizable(false);this.setDefaultCloseOperation(EXIT_ON_CLOSE);this.setVisible(true);}public Test(String title) {super(title);this.setLayout(null); //不使⽤布局管理器,每个控件的位置⽤setBounds设定jb = new JButton[MINE_SIZE][MINE_SIZE];jl = new JLabel();showTime = new JLabel();map = new int[MINE_SIZE][MINE_SIZE]; // 将按钮映射到数组中}public static void main(String[] args) {Test test = new Test("Hello Miner!");test.init();test.run();}@Overridepublic void actionPerformed(ActionEvent e) {Object obj = e.getSource();int x, y;if ((obj instanceof JButton) == false) {showMessage("错误", "内部错误");return;}String[] tmp_str = ((JButton) obj).getName().split("_");x = Integer.parseInt(tmp_str[0]);y = Integer.parseInt(tmp_str[1]);if (map[x][y] == MINE) {showMessage("死亡", "你踩到地雷啦~~~");flag = true;showMine();return;}dfs(x, y, 0);checkSuccess();}/*** 每次点击完后,判断有没有把全部雷都找到通过计算状态为enable的按钮的个数来判断 */private void checkSuccess() {int cnt = 0;for (int i = 0; i < MINE_SIZE; i++) {for (int j = 0; j < MINE_SIZE; j++) {if (jb[i][j].isEnabled()) {cnt++;}}}if (cnt == MINE_COUNT) {String tmp_str = showTime.getText();tmp_str = tmp_str.replaceAll("[^0-9]", "");showMessage("胜利", "本次扫雷共⽤时:" + tmp_str + "秒");flag = true;showMine();}}private int dfs(int x, int y, int d) {map[x][y] = CHECKED;int i, tx, ty, cnt = 0;for (i = 0; i < 8; i++) {tx = x + mv[i][0];ty = y + mv[i][1];if (tx >= 0 && tx < MINE_SIZE && ty >= 0 && ty < MINE_SIZE) {if (map[tx][ty] == MINE) {cnt++;// 该点附近雷数统计} else if (map[tx][ty] == EMPTY) {;} else if (map[tx][ty] == CHECKED) {;}}}if (cnt == 0) {for (i = 0; i < 8; i++) {tx = x + mv[i][0];ty = y + mv[i][1];if (tx >= 0 && tx < MINE_SIZE && ty >= 0 && ty < MINE_SIZE&& map[tx][ty] != CHECKED) {dfs(tx, ty, d + 1);}}} else {jb[x][y].setText(cnt + "");}jb[x][y].setEnabled(false);return cnt;}/*** 在jl标签上显⽰⼀些信息** @param title* @param info*/private void showMessage(String title, String info) {jl.setText(info);System.out.println("in functino showMessage() : " + info);}public void run() {int t = 0;while (true) {if (flag) {break;}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}t++;showTime.setText("已⽤时:" + t + " 秒");}// showMine();}private void showMine() {// Icon iconMine = new ImageIcon("e:/mine.jpg");for (int i = 0; i < MINE_SIZE; i++) {for (int j = 0; j < MINE_SIZE; j++) {if (map[i][j] == MINE) {jb[i][j].setText("#");// jb[i][j].setIcon(iconMine);}}}}@Overridepublic void mouseClicked(MouseEvent e) {if (e.getButton() == 3) {Object obj = e.getSource();if ((obj instanceof JButton) == false) {showMessage("错误", "内部错误");return;}String[] tmp_str = ((JButton) obj).getName().split("_");int x = Integer.parseInt(tmp_str[0]);int y = Integer.parseInt(tmp_str[1]);if ("{1}quot;.equals(jb[x][y].getText())) {jb[x][y].setText("");} else {jb[x][y].setText("{1}quot;);}/* if(jb[x][y].getIcon() == null){jb[x][y].setIcon(new ImageIcon("e:/flag.jpg"));}else{jb[x][y].setIcon(null);}*/}}@Overridepublic void mousePressed(MouseEvent e) {// TODO Auto-generated method stub}@Overridepublic void mouseReleased(MouseEvent e) {// TODO Auto-generated method stub}@Overridepublic void mouseEntered(MouseEvent e) {// TODO Auto-generated method stub}@Overridepublic void mouseExited(MouseEvent e) {// TODO Auto-generated method stub}}更多精彩游戏,请参考专题以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
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这门语⾔也有了⽐以前更深刻的认识。
J a v a编写的扫雷小程序 The document was finally revised on 2021整个程序使用了4个类:Game 用于启动程序, 界面的布置,各种行列的算法。
ExtendButton 继承了Jbutton 用于新建button的各种属性ShowNum 监听到某个button后,计算出此button周围有几个雷,不同的雷对应不通的图片,类得到button上应加载的图片地址ViewReSet 此类用于新建一个窗口,用户输入自己想要的行、列、雷数,然后用新的行列雷数new一个新的Gamebiaose dise1 dise2 dise3dise4 dise5 dise6 dise7dise8 dise lei biaoji/****************************************************************运行类创建游戏主窗体*/package class Game extends JFrame implements ActionListener{private Container myContainer;private GridLayout myLayout;private JPanel myPanelMain;private JPanel myPanel;private JToolBar myTool;private JLabel time;private JLabel labelTime;private JLabel bombNum;private JLabel labelBombNum;private JMenuBar menuBar;private JMenu menuE, menuH;private JMenuItem menuItemCZ, menuItemSZ;private int numBomb, countTime, leaveBomb, numEnd;private int myRows, myColumns;private int xis, yis;private Timer timer;private ExtendButton[] myButton = null;etPostion(i);[i].setIcon((newShowNum(10)).getImageIcon());[i].setButton_num(0);[i].SetVisited(false);[i].SetStatus(false);ddMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent evt) {if (() == ) {int n =((ExtendButton)()).getButton_num();if(n == 1) {if(!((ExtendButton)()).GetVisited()) {((ExtendButton)()).setButton_num(0);((ExtendButton)()).setIcon((newShowNum(10)).getImageIcon());leaveBomb++;(leaveBomb));}} else {if(!((ExtendButton)()).GetVisited()) {((ExtendButton)()).setButton_num(1);((ExtendButton)()).setIcon((newShowNum(11)).getImageIcon());leaveBomb--;(leaveBomb));}}}}});[i].addActionListener(this);}();;show();etVisited(false);[i].SetStatus(false);[i].setText(null);[i].setIcon((newShowNum(10)).getImageIcon());}(numBomb);= numBomb;= * - leaveBomb;}etStatus()) {[tempint].SetStatus(true);counter++;}}}etStatus()) {[i].setIcon((newShowNum(9)).getImageIcon());}}}etStatus() && !myButton[CircleNum[i]].GetVisited()) {temp++;}}}etImageIcon());temp = 0;} else if(temp == 0) {(true);((new ShowNum(0)).getImageIcon());for (int i = 0; i < 8; i++) {if(CircleNum[i] != -1&& !myButton[CircleNum[i]].GetVisited()) {CheckButton(myButton[CircleNum[i]]);}}};if == 0) {(this, "恭喜你!", "消息", ;ShowBomb();}}}etScreenSize();int x = (int) (() - 400) / 2);int y = (int) (() - 500) / 2);= 300;= 400;(x, y, , ;("扫雷");= 10;= 9;= 9;();();;}public Game(int row, int column, int numbomb) {Dimension dimension = ().getScreenSize();int x = (int) (() - 400) / 2);int y = (int) (() - 500) / 2);= 310 * column /9;= 300 * row / 9 + 100;(x, y, , ;("扫雷");= row;= column;= numbomb;();();;}class/images/");break;case 1:imageIcon = new ImageIcon("./class/images/");break;case 2:imageIcon = new ImageIcon("./class/images/");break;case 3:imageIcon = new ImageIcon("./class/images/");break;imageIcon = new ImageIcon("./class/images/");break;case 5:imageIcon = new ImageIcon("./class/images/");break;case 6:imageIcon = new ImageIcon("./class/images/");break;case 7:imageIcon = new ImageIcon("./class/images/");break;case 8:imageIcon = new ImageIcon("./class/images/");break;case 9:imageIcon = new ImageIcon("./class/images/");break;case 10:imageIcon = new ImageIcon("./class/images/");break;case 11:imageIcon = new ImageIcon("./class/images/");break;default:imageIcon = newImageIcon("./class/images/");break;}return imageIcon;}}/********************************************************************创建一个新窗口,输入新的行、列、雷数,然后用新数据重新new一个Game窗口*/package class ViewReSet extends JDialog implements ActionListener{private JFrame frame = null;private JPanel myPanel = null;private JLabel myLabel = null;private JLabel myLabelRow = null;private JLabel myLabelColum = null;private JLabel myLabelBombNum = null;private JTextField myFieldRow = null;private JTextField myFieldColum = null;private JTextField myFieldBombNum = null;private JButton buttonOK = null;private JButton buttonReset = null;private int row;private int column;private int bombNum;private int [] myrcb = new int [3];private void createView(){Container container = ();= new JPanel(new GridBagLayout());;GridBagConstraints gbc = new GridBagConstraints();= 1;= 0;= new JLabel("窗口行列设置");gbc);= 0;= 1;= new JLabel("行数:");gbc);= 1;= 1;= new JTextField(10);gbc);= 0;= 2;= new JLabel("列数:");gbc);= 1;= 2;= new JTextField(10);gbc);= 0;= 3;= new JLabel("雷数:");gbc);= 1;= 3;= new JTextField(10);gbc);JPanel btnPanel = new JPanel();(false);= new JButton("确定");;= new JButton("重置");;= 1;= 4;gbc);("设置");;}public ViewReSet(int r, int c, int b) { Dimension dimension = ().getScreenSize();int xAxis = (int) (() - 300) / 2);int yAyis = (int) (() - 200) / 2);(xAxis, yAyis, 300, 200);[0] = r;[1] = c;[2] = b;();(true);}public void actionPerformed(ActionEvent e) {if() == {} else if() == {String r, c, b;r = if() > 0) {= (r);} else {= [0];}c = if() > 0) {= (c);} else {= [1];}b = if() > 0) {= } else {= [2];}new Game, , ;();}}}。
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()这个⽅法,运⾏程序,显⽰如下:⾄此,我们已经完成了扫雷游戏的⼀半程序,只剩下填充按钮和点击按钮后发⽣的逻辑判断了,这些将在中继续分享完整详细代码(已注释好)已经附在下⼀篇博客中,供交流和学习,欢迎查阅更多精彩游戏,请参考专题以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
importjava.util.Scanner;public class SL {public static void main(String[] args) {Scanner s = new Scanner(System.in);int[][] square = null;String[][] draw = null;boolean flag = true;while(flag){System.out.println("请选择游戏难度");System.out.println("1:简单");System.out.println("2: 一般");System.out.println("3: 困难");intuserselect = s.nextInt();if(userselect!=1 &&userselect!=2 &&userselect!=3){System.out.println("您的输入有误,请重新输入");continue;}switch(userselect){case 1: square = new int[3][3];draw = new String[3][3];break;case 2: square = new int[6][6];draw= new String[6][6];break;case 3: square = new int[9][9];draw= new String[9][9];break;}for(int i =0;i<square.length;i++){for(int j=0;j<square[i].length;j++){square[i][j] = (int)(Math.random()*10/5);draw[i][j] = "*";System.out.print(square[i][j]+" ");}System.out.println("");}for(int i =0;i<square.length;i++){for(int j=0;j<square[i].length;j++){System.out.print("* ");}System.out.println("");}System.out.println("游戏开始");System.out.println("如果您觉得有雷,请输入:1"); System.out.println("如果您觉得没雷,请输入:0");R1:for(int i=0;i<square.length;i++){for(int j=0;j<square[i].length;j++){byte input = -1;while(flag){System.out.println("您觉得"+(i+1)+"-"+(j+1)+"位置上是否有雷"); input = s.nextByte();if(input!=0 && input!=1){System.out.println("您的输入有误,请重新输入");continue;}break;}if(input==square[i][j]){System.out.println("排除成功");draw[i][j] = String.valueOf(square[i][j]);for(int a =0;a<draw.length;a++){for(int b=0;b<draw[i].length;b++){System.out.print(draw[a][b]+" ");}System.out.println();}int x = i;int y = j;int counter =0;while(true){if(x-1>=0 && y-1>=0){counter += square[(x-1)][(y-1)];System.out.println("周围有"+counter+"颗雷");break;}else if(x-1<0){System.out.println("2");x++;}else if(y-1<0){System.out.println("3");y++;}}}else{System.out.println("游戏结束");break R1;}}}System.out.println("恭喜您过关成功");byteuserchoose = -1;while(flag){System.out.println("是否继续");System.out.println("继续请按:1");System.out.println("退出请按:0");userchoose = s.nextByte();if(userchoose!=0 &&userchoose!=1){System.out.println("您的输入有误请重新输入");continue;}break;}if(userchoose==0){break;}}}}。
扫雷使用Java语言和JavaFX开发的小游戏扫雷游戏是一款经典的单人益智游戏,目标是在一个方块网格中,找出所有不含雷的方块,同时避开所有含雷的方块。
本文将介绍如何使用Java语言和JavaFX开发一个简单的扫雷游戏。
一、游戏设计和规则扫雷游戏的设计和规则非常简单。
一个方块网格被分成若干个小方块,有些方块上隐藏着雷,而其他方块上则显示着数字,数字表示该方块周围的雷数。
玩家可以点击方块来揭示它的内容,如果揭示到含雷的方块,则游戏结束;如果揭示到数字方块,则继续进行游戏;若揭示到不含雷的方块,则继续揭示周围的方块,直到揭示到含雷的方块或者揭示到边界为止。
游戏目标是揭示出所有不含雷的方块。
二、项目结构与主要类在Java语言和JavaFX开发扫雷游戏时,一个推荐的项目结构如下:1. Main类:游戏的入口类,负责启动游戏。
2. Game类:游戏的主要逻辑类,包含方块网格的生成、雷的布置以及游戏状态的管理。
3. Block类:方块类,包含方块的状态(是否揭示、是否含雷等)和周围雷数的计算方法。
4. UI类:游戏的用户界面类,负责显示方块网格和处理点击事件等。
三、使用JavaFX创建用户界面JavaFX是现代化的Java图形界面开发框架,提供了丰富的界面组件和动画效果。
在扫雷游戏中,可以使用JavaFX来实现方块的显示以及用户交互。
1. 创建方块网格:使用JavaFX的GridPane布局来创建方块网格。
可以根据游戏难度在GridPane中添加若干个方块组件,并设置它们的样式和事件处理器。
2. 显示方块内容:根据方块的状态,在界面上显示相应的图标或者文字。
可以使用JavaFX的Label组件来显示方块的内容,并根据不同的状态设置不同的样式。
3. 处理点击事件:为每个方块组件添加事件处理器,当用户点击方块时,根据方块的内容和状态来更新界面显示。
四、实现游戏逻辑在Game类中实现游戏的主要逻辑。
首先,根据游戏难度生成方块网格,并在其中随机布置一定数量的雷。
java实现简单扫雷⼩游戏本⽂实例为⼤家分享了java实现扫雷游戏的具体代码,供⼤家参考,具体内容如下import java.awt.BorderLayout;import java.awt.Color;import java.awt.Container;import java.awt.GridLayout;import java.awt.Insets;import bel;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.ItemEvent;import java.awt.event.ItemListener;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.util.Random;import javax.swing.JButton;import javax.swing.JComboBox;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JPanel;public class SaoLei implements MouseListener,ActionListener{JPanel p=new JPanel();JFrame frame = new JFrame("扫雷");@SuppressWarnings("rawtypes")JComboBox combobox = new JComboBox();JButton reset = new JButton("重新开始");Container container = new Container();//游戏数据结构SaoLeiConstant constant = new SaoLeiConstant();JButton[][] buttons = new JButton[constant.row][constant.col];//定义按钮int[][] counts = new int [constant.row][constant.col];//定义整型数组保存按钮下⽅雷数//创建构造⽅法public SaoLei() {//显⽰窗⼝frame.setSize(600,700);//600*700frame.setResizable(false);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setLayout(new BorderLayout());//添加重来、选择难度按钮addtopButton();//添加雷区按钮addButtons();//埋雷addLei();//添加雷的计数calcNeiboLei();frame.setVisible(true);}void addtopButton() {p.removeAll();p.add(reset);reset.setBackground(Color.green);reset.setOpaque(true);reset.addActionListener(this);//combobox.addItem("选择难度");combobox.addItem("新⼿难度");combobox.addItem("初级难度");combobox.addItem("中级难度");combobox.addItem("⾼级难度");combobox.addItem("⼤师难度");combobox.setBackground(Color.GREEN);@Overridepublic void itemStateChanged(ItemEvent e) {String item = e.getItem().toString();if(item == "新⼿难度") {constant.leiCount = 20;ResetGame();} else if(item == "初级难度") {constant.leiCount = 43;ResetGame();} else if(item == "中级难度"){constant.leiCount = 63;ResetGame();} else if(item == "⾼级难度"){constant.leiCount = 99;ResetGame();} else if(item == "⼤师难度") {constant.leiCount = 119;ResetGame();}}});p.add(combobox);frame.add(p,BorderLayout.NORTH);//p.add(new Label("总雷数:"+constant.leiCount,Label.CENTER)); //p.add(new Label("总雷数:"+constant.leiCount,Label.RIGHT)); }/*void addnanduButton() {nandu.setBackground(Color.green);nandu.setOpaque(true);nandu.addActionListener(this);frame.add(nandu,BorderLayout.WEST);}void addResetButton() {reset.setBackground(Color.green);reset.setOpaque(true);reset.addActionListener(this);//reset.addMouseListener(this);frame.add(reset,BorderLayout.NORTH);}*/void addLei() {Random rand = new Random();int randRow,randCol;for(int i=0; i<constant.leiCount; i++) {randRow = rand.nextInt(constant.row);randCol = rand.nextInt(constant.col);if(counts[randRow][randCol] == constant.LEICODE) {i--;} else {counts[randRow][randCol] = constant.LEICODE;//buttons[randRow][randCol].setText("X");}}}void addButtons() {frame.add(container,BorderLayout.CENTER);container.setLayout(new GridLayout(constant.row,constant.col)); for(int i=0;i<constant.row;i++) {for(int j=0;j<constant.col;j++) {JButton button = new JButton();button.setBackground(Color.white);button.setOpaque(true);button.addActionListener(this);button.addMouseListener((MouseListener) this);buttons[i][j] = button;}}void calcNeiboLei() {int count;for(int i=0;i<constant.row;i++) {for(int j=0;j<constant.col;j++) {count =0;if(counts[i][j] == constant.LEICODE) continue;if(i>0 && j>0 && counts[i-1][j-1] == constant.LEICODE) count++;if(i>0 && counts[i-1][j] == constant.LEICODE) count++;if(i>0 && j<19 &&counts[i-1][j+1] == constant.LEICODE) count++;if(j>0 && counts[i][j-1] == constant.LEICODE) count++;if(j<19 && counts[i][j+1] == constant.LEICODE) count++;if(i<19 && j>0 && counts[i+1][j-1] == constant.LEICODE) count++;if(i<19 && counts[i+1][j] == constant.LEICODE) count++;if(i<19 && j<19 && counts[i+1][j+1] == constant.LEICODE) count++; counts[i][j] = count;buttons[i][j].setMargin(new Insets(0,0,0,0));//让按钮随按钮上的图案变化 //buttons[i][j].setText(counts[i][j] + "");}}}@Overridepublic void actionPerformed(ActionEvent e) {JButton button = (JButton)e.getSource();if(button.equals(reset)) {ResetGame();//重新开始游戏} else {int count = 0;for(int i=0;i<constant.row;i++) {for(int j=0;j<constant.col;j++) {if(button.equals(buttons[i][j])) {count = counts[i][j];if(count == constant.LEICODE) {loseGame();} else {openCell(i,j);checkWin();}return;}}}}}public void mouseClicked(MouseEvent e) {JButton button = (JButton)e.getSource();if (e.getButton() == MouseEvent.BUTTON3) {//判断⿏标右击动作for(int i=0;i<constant.row;i++) {for(int j=0;j<constant.col;j++) {if(button.equals(buttons[i][j])) {if((buttons[i][j].isEnabled() == true)) {//buttons[i][j].setEnabled(false);buttons[i][j].setMargin(new Insets(0,0,0,0));//让按钮随按钮上的图案变化 buttons[i][j].setText("?");return;}}}}}}void ResetGame() {for(int i=0;i<constant.row;i++) {for(int j=0;j<constant.col;j++) {buttons[i][j].setText("");buttons[i][j].setEnabled(true);buttons[i][j].setBackground(Color.white);counts[i][j] = 0;calcNeiboLei();}void checkWin() {for(int i=0;i<constant.row;i++) {for(int j=0;j<constant.col;j++) {if(buttons[i][j].isEnabled() == true && counts[i][j] != constant.LEICODE ) return; }}JOptionPane.showMessageDialog(frame,"Yeah,你赢了!");}//使⽤递归⽅法打开格⼦void openCell(int i, int j) {if(buttons[i][j].isEnabled() == false) return;buttons[i][j].setBackground(Color.yellow);buttons[i][j].setOpaque(true);buttons[i][j].setEnabled(false);if(counts[i][j] == 0) {if(i>0 && j>0 && counts[i-1][j-1] != constant.LEICODE) openCell(i-1,j-1);if(i>0 && j<19 && counts[i-1][j] != constant.LEICODE) openCell(i-1,j);if(i>0 && j<19 &&counts[i-1][j+1] != constant.LEICODE) openCell(i-1,j+1);if(j>0 && counts[i][j-1] != constant.LEICODE) openCell(i,j-1);if(j<19 && counts[i][j+1] != constant.LEICODE) openCell(i,j+1);if(i<19 && j>0 && counts[i+1][j-1] != constant.LEICODE) openCell(i+1,j-1);if(i<19 && counts[i+1][j] != constant.LEICODE) openCell(i+1,j);if(i<19 && j<19 && counts[i+1][j+1] != constant.LEICODE) openCell(i+1,j+1); } else {buttons[i][j].setMargin(new Insets(0,0,0,0));buttons[i][j].setText(counts[i][j] + "");}}void loseGame() {for(int i=0;i<constant.row;i++) {for(int j=0;j<constant.col;j++) {int count = counts[i][j];if(count == constant.LEICODE) {buttons[i][j].setMargin(new Insets(0,0,0,0));buttons[i][j].setText("雷");buttons[i][j].setBackground(Color.red);buttons[i][j].setEnabled(false);} else {buttons[i][j].setMargin(new Insets(0,0,0,0));buttons[i][j].setText(count + "");buttons[i][j].setEnabled(false);}}}JOptionPane.showMessageDialog(frame,"error,你输了!");}public static void main(String[] args) {new SaoLei();}@Overridepublic void mousePressed(MouseEvent e) {// TODO Auto-generated method stub}@Overridepublic void mouseReleased(MouseEvent e) {// TODO Auto-generated method stub}@Overridepublic void mouseEntered(MouseEvent e) {// TODO Auto-generated method stubpublic void mouseExited(MouseEvent e) {// TODO Auto-generated method stub}}常量类public class SaoLeiConstant {final int row = 20;//⾏数30final int col = 20;//列数30final int LEICODE = 10;//定义雷下⽅的数字protected int temp = 20;protected int leiCount = temp;//雷数30}效果图更多精彩游戏,请参考专题以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
教你使⽤Java实现扫雷⼩游戏(最新完整版)⽬录效果展⽰主类:GameWin类底层地图MapBottom类顶层地图MapTop类底层数字BottomNum类初始化地雷BottomRay类⼯具GameUtil类总结⼤家好,我是orangemilk_,哈哈,学习Java已经到⼀个阶段啦,今天我们使⽤GUI来写⼀个扫雷⼩游戏吧!效果展⽰主类:GameWin类package com.sxt;import javax.swing.*;import java.awt.*;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;public class GameWin extends JFrame {int width = 2 * GameUtil.OFFSET + GameUtil.MAP_W * GameUtil.SQUARE_LENGTH;int height = 4 * GameUtil.OFFSET + GameUtil.MAP_H * GameUtil.SQUARE_LENGTH;Image offScreenImage = null;MapBottom mapBottom = new MapBottom();MapTop mapTop = new MapTop();void launch(){GameUtil.START_TIME=System.currentTimeMillis();this.setVisible(true);this.setSize(width,height);this.setLocationRelativeTo(null);this.setTitle("Java扫雷⼩游戏");this.setDefaultCloseOperation(EXIT_ON_CLOSE);//⿏标事件this.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {super.mouseClicked(e);switch (GameUtil.state){case 0 :if(e.getButton()==1){GameUtil.MOUSE_X = e.getX();GameUtil.MOUSE_Y = e.getY();GameUtil.LEFT = true;}if(e.getButton()==3) {GameUtil.MOUSE_X = e.getX();GameUtil.MOUSE_Y = e.getY();GameUtil.RIGHT = true;}//去掉break,任何时候都监听⿏标事件case 1 :case 2 :if(e.getButton()==1){if(e.getX()>GameUtil.OFFSET + GameUtil.SQUARE_LENGTH*(GameUtil.MAP_W/2)&& e.getX()<GameUtil.OFFSET + GameUtil.SQUARE_LENGTH*(GameUtil.MAP_W/2) + GameUtil.SQUARE_LENGTH&& e.getY()>GameUtil.OFFSET&& e.getY()<GameUtil.OFFSET+GameUtil.SQUARE_LENGTH){mapBottom.reGame();mapTop.reGame();GameUtil.FLAG_NUM=0;GameUtil.START_TIME=System.currentTimeMillis();GameUtil.state=0;break;default:}}});while (true){repaint();try {Thread.sleep(40);} catch (InterruptedException e) {e.printStackTrace();}}}@Overridepublic void paint(Graphics g) {offScreenImage = this.createImage(width,height);Graphics gImage = offScreenImage.getGraphics();//设置背景颜⾊gImage.setColor(Color.lightGray);gImage.fillRect(0,0,width,height);mapBottom.paintSelf(gImage);mapTop.paintSelf(gImage);g.drawImage(offScreenImage,0,0,null);}public static void main(String[] args) {GameWin gameWin = new GameWin();unch();}}底层地图MapBottom类//底层地图:绘制游戏相关组件package com.sxt;import java.awt.*;public class MapBottom {BottomRay bottomRay = new BottomRay();BottomNum bottomNum = new BottomNum();{bottomRay.newRay();bottomNum.newNum();}//重置游戏void reGame(){for (int i = 1; i <=GameUtil.MAP_W ; i++) {for (int j = 1; j <=GameUtil.MAP_H ; j++) {GameUtil.DATA_BOTTOM[i][j]=0;}}bottomRay.newRay();bottomNum.newNum();}//绘制⽅法void paintSelf(Graphics g){g.setColor(Color.BLACK);//画竖线for (int i = 0; i <= GameUtil.MAP_W; i++) {g.drawLine(GameUtil.OFFSET + i * GameUtil.SQUARE_LENGTH,3*GameUtil.OFFSET,GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH,3*GameUtil.OFFSET+GameUtil.MAP_H*GameUtil.SQUARE_LENGTH);}//画横线for (int i = 0; i <=GameUtil.MAP_H; i++){g.drawLine(GameUtil.OFFSET,3*GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH,GameUtil.OFFSET+GameUtil.MAP_W*GameUtil.SQUARE_LENGTH,3*GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH);}for (int i = 1; i <= GameUtil.MAP_W ; i++) {for (int j = 1; j <= GameUtil.MAP_H; j++) {//雷if (GameUtil.DATA_BOTTOM[i][j] == -1) {g.drawImage(GameUtil.lei,GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 1,GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 1,GameUtil.SQUARE_LENGTH - 2,GameUtil.SQUARE_LENGTH - 2,null);}//数字if (GameUtil.DATA_BOTTOM[i][j] >=0) {g.drawImage(GameUtil.images[GameUtil.DATA_BOTTOM[i][j]],GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 15,GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 5,null);}}}//绘制数字,剩余雷数,倒计时GameUtil.drawWord(g,""+(GameUtil.RAY_MAX-GameUtil.FLAG_NUM),GameUtil.OFFSET,2*GameUtil.OFFSET,30,Color.red);GameUtil.drawWord(g,""+(GameUtil.END_TIME-GameUtil.START_TIME)/1000,GameUtil.OFFSET + GameUtil.SQUARE_LENGTH*(GameUtil.MAP_W-1),2*GameUtil.OFFSET,30,Color.red);switch (GameUtil.state){case 0:GameUtil.END_TIME=System.currentTimeMillis();g.drawImage(GameUtil.face,GameUtil.OFFSET + GameUtil.SQUARE_LENGTH * (GameUtil.MAP_W/2), GameUtil.OFFSET,null);break;case 1:g.drawImage(GameUtil.win,GameUtil.OFFSET + GameUtil.SQUARE_LENGTH * (GameUtil.MAP_W/2), GameUtil.OFFSET,null);g.drawImage(GameUtil.over,GameUtil.OFFSET + GameUtil.SQUARE_LENGTH * (GameUtil.MAP_W/2),GameUtil.OFFSET,null);break;default:}}}顶层地图MapTop类顶层地图类:绘制顶层组件package com.sxt;import java.awt.*;public class MapTop {//格⼦位置int temp_x;int temp_y;//重置游戏void reGame(){for (int i = 1; i <=GameUtil.MAP_W ; i++) {for (int j = 1; j <=GameUtil.MAP_H ; j++) {GameUtil.DATA_TOP[i][j]=0;}}}//判断逻辑void logic(){temp_x=0;temp_y=0;if(GameUtil.MOUSE_X>GameUtil.OFFSET && GameUtil.MOUSE_Y>3*GameUtil.OFFSET){ temp_x = (GameUtil.MOUSE_X - GameUtil.OFFSET)/GameUtil.SQUARE_LENGTH+1;temp_y = (GameUtil.MOUSE_Y - GameUtil.OFFSET * 3)/GameUtil.SQUARE_LENGTH+1; }if(temp_x>=1 && temp_x<=GameUtil.MAP_W&& temp_y>=1 && temp_y<=GameUtil.MAP_H){if(GameUtil.LEFT){//覆盖,则翻开if(GameUtil.DATA_TOP[temp_x][temp_y]==0){GameUtil.DATA_TOP[temp_x][temp_y]=-1;}spaceOpen(temp_x,temp_y);GameUtil.LEFT=false;}if(GameUtil.RIGHT){//覆盖则插旗if(GameUtil.DATA_TOP[temp_x][temp_y]==0){GameUtil.DATA_TOP[temp_x][temp_y]=1;GameUtil.FLAG_NUM++;}//插旗则取消else if(GameUtil.DATA_TOP[temp_x][temp_y]==1){GameUtil.DATA_TOP[temp_x][temp_y]=0;GameUtil.FLAG_NUM--;}else if(GameUtil.DATA_TOP[temp_x][temp_y]==-1){numOpen(temp_x,temp_y);}GameUtil.RIGHT=false;}}boom();victory();}//数字翻开void numOpen(int x,int y){//记录旗数int count=0;if(GameUtil.DATA_BOTTOM[x][y]>0){for (int i = x-1; i <=x+1 ; i++) {for (int j = y-1; j <=y+1 ; j++) {if(GameUtil.DATA_TOP[i][j]==1){count++;}}}if(count==GameUtil.DATA_BOTTOM[x][y]){for (int i = x-1; i <=x+1 ; i++) {for (int j = y-1; j <=y+1 ; j++) {if(GameUtil.DATA_TOP[i][j]!=1){GameUtil.DATA_TOP[i][j]=-1;}//必须在雷区当中if(i>=1&&j>=1&&i<=GameUtil.MAP_W&&j<=GameUtil.MAP_H){spaceOpen(i,j);}}}}}}//失败判定 t 表⽰失败 f 未失败boolean boom(){if(GameUtil.FLAG_NUM==GameUtil.RAY_MAX){for (int i = 1; i <=GameUtil.MAP_W ; i++) {for (int j = 1; j <=GameUtil.MAP_H ; j++) {if(GameUtil.DATA_TOP[i][j]==0){GameUtil.DATA_TOP[i][j]=-1;}}}}for (int i = 1; i <=GameUtil.MAP_W ; i++) {for (int j = 1; j <=GameUtil.MAP_H ; j++) {if(GameUtil.DATA_BOTTOM[i][j]==-1&&GameUtil.DATA_TOP[i][j]==-1){GameUtil.state = 2;seeBoom();return true;}}//失败显⽰void seeBoom(){for (int i = 1; i <=GameUtil.MAP_W ; i++) {for (int j = 1; j <=GameUtil.MAP_H ; j++) {//底层是雷,顶层不是旗,显⽰if(GameUtil.DATA_BOTTOM[i][j]==-1&&GameUtil.DATA_TOP[i][j]!=1){GameUtil.DATA_TOP[i][j]=-1;}//底层不是雷,顶层是旗,显⽰差错旗if(GameUtil.DATA_BOTTOM[i][j]!=-1&&GameUtil.DATA_TOP[i][j]==1){GameUtil.DATA_TOP[i][j]=2;}}}}//胜利判断 t 表⽰胜利 f 未胜利boolean victory(){//统计未打开格⼦数int count=0;for (int i = 1; i <=GameUtil.MAP_W ; i++) {for (int j = 1; j <=GameUtil.MAP_H ; j++) {if(GameUtil.DATA_TOP[i][j]!=-1){count++;}}}if(count==GameUtil.RAY_MAX){GameUtil.state=1;for (int i = 1; i <=GameUtil.MAP_W ; i++) {for (int j = 1; j <=GameUtil.MAP_H ; j++) {//未翻开,变成旗if(GameUtil.DATA_TOP[i][j]==0){GameUtil.DATA_TOP[i][j]=1;}}}return true;}return false;}//打开空格void spaceOpen(int x,int y){if(GameUtil.DATA_BOTTOM[x][y]==0){for (int i = x-1; i <=x+1 ; i++) {for (int j = y-1; j <=y+1 ; j++) {//覆盖,才递归if(GameUtil.DATA_TOP[i][j]!=-1){if(GameUtil.DATA_TOP[i][j]==1){GameUtil.FLAG_NUM--;}GameUtil.DATA_TOP[i][j]=-1;//必须在雷区当中if(i>=1&&j>=1&&i<=GameUtil.MAP_W&&j<=GameUtil.MAP_H){spaceOpen(i,j);}}}}}}//绘制⽅法void paintSelf(Graphics g){logic();for (int i = 1; i <= GameUtil.MAP_W ; i++) {for (int j = 1; j <= GameUtil.MAP_H; j++) {//覆盖if (GameUtil.DATA_TOP[i][j] == 0) {g.drawImage(GameUtil.top,GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 1,GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 1, GameUtil.SQUARE_LENGTH - 2,GameUtil.SQUARE_LENGTH - 2,null);}//插旗if (GameUtil.DATA_TOP[i][j] == 1) {g.drawImage(GameUtil.flag,GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 1,GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 1, GameUtil.SQUARE_LENGTH - 2,GameUtil.SQUARE_LENGTH - 2,null);}//差错旗if (GameUtil.DATA_TOP[i][j] == 2) {g.drawImage(GameUtil.noflag,GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 1,GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 1, GameUtil.SQUARE_LENGTH - 2,GameUtil.SQUARE_LENGTH - 2,null);}}}}}底层数字BottomNum类//底层数字类package com.sxt;public class BottomNum {void newNum() {for (int i = 1; i <=GameUtil.MAP_W ; i++) {for (int j = 1; j <=GameUtil.MAP_H ; j++) {if(GameUtil.DATA_BOTTOM[i][j]==-1){for (int k = i-1; k <=i+1 ; k++) {for (int l = j-1; l <=j+1 ; l++) {if(GameUtil.DATA_BOTTOM[k][l]>=0){}}}}}}初始化地雷BottomRay类//初始化地雷类package com.sxt;public class BottomRay {//存放坐标int[] rays = new int[GameUtil.RAY_MAX*2];//地雷坐标int x,y;//是否放置 T 表⽰可以放置 F 不可放置boolean isPlace = true;//⽣成雷void newRay() {for (int i = 0; i < GameUtil.RAY_MAX*2 ; i=i+2) {x= (int) (Math.random()*GameUtil.MAP_W +1);//1-12y= (int) (Math.random()*GameUtil.MAP_H +1);//1-12//判断坐标是否存在for (int j = 0; j < i ; j=j+2) {if(x==rays[j] && y==rays[j+1]){i=i-2;isPlace = false;break;}}//将坐标放⼊数组if(isPlace){rays[i]=x;rays[i+1]=y;}isPlace = true;}for (int i = 0; i < GameUtil.RAY_MAX*2; i=i+2) {GameUtil.DATA_BOTTOM[rays[i]][rays[i+1]]=-1;}}}⼯具GameUtil类//⼯具类:存放静态参数,⼯具⽅法package com.sxt;import java.awt.*;public class GameUtil {//地雷个数static int RAY_MAX = 5;//地图的宽static int MAP_W = 11;//地图的⾼static int MAP_H = 11;//雷区偏移量static int OFFSET = 45;//格⼦边长static int SQUARE_LENGTH = 50;//插旗数量static int FLAG_NUM = 0;//⿏标相关//坐标static int MOUSE_X;static int MOUSE_Y;//状态static boolean LEFT = false;static boolean RIGHT = false;//游戏状态 0 表⽰游戏中 1 胜利 2 失败static int state = 0;//倒计时static long START_TIME;static long END_TIME;//底层元素 -1 雷 0 空 1-8 表⽰对应数字static int[][] DATA_BOTTOM = new int[MAP_W+2][MAP_H+2];//顶层元素 -1 ⽆覆盖 0 覆盖 1 插旗 2 差错旗static int[][] DATA_TOP = new int[MAP_W+2][MAP_H+2];//载⼊图⽚static Image lei = Toolkit.getDefaultToolkit().getImage("imgs/lei.png");static Image top = Toolkit.getDefaultToolkit().getImage("imgs/top.gif");static Image flag = Toolkit.getDefaultToolkit().getImage("imgs/flag.gif");static Image noflag = Toolkit.getDefaultToolkit().getImage("imgs/noflag.png");static Image face = Toolkit.getDefaultToolkit().getImage("imgs/face.png");static Image over = Toolkit.getDefaultToolkit().getImage("imgs/over.png");static Image win = Toolkit.getDefaultToolkit().getImage("imgs/win.png");static Image[] images = new Image[9];static {for (int i = 1; i <=8 ; i++) {images[i] = Toolkit.getDefaultToolkit().getImage("imgs/num/"+i+".png");}}static void drawWord(Graphics g,String str,int x,int y,int size,Color color){g.setColor(color);g.setFont(new Font("仿宋",Font.BOLD,size));g.drawString(str,x,y);}}总结在使⽤Java编写扫雷⼩游戏时遇到了很多问题,在解决问题时,确实对java的⾯向对象编程有了更加深⼊的理解。
1设计题目及具体要求设计题目:扫雷游戏的开发题目需求:玩者进入游戏后,开始游戏,目的是为了找出所有隐藏的小方格后一定数目地雷,进行标记,把所有地雷找出并用时最少的胜利者进出扫雷英雄榜。
单击游戏菜单可以选择<初级>,<高级>,<中级>和<扫雷英雄榜>。
扫雷的各个级别是根据游戏的总格子数和地雷总数来区别的,初级的总格子数最少,地雷数也最少,高级的总格子数和地雷数最多。
扫雷英雄榜中记录着各个级别的第一名玩家,而且玩家可以刷新纪录。
游戏上方可以显示这盘中还有多少颗地雷,还可以显示在这盘游戏中游戏进行了多长时间。
选择级别后游戏去会出现相应的扫雷区域,这是玩家用鼠标单击任意一个方格,开始计时及游戏开始。
玩家要揭开某个方块可单击它,若该方块不是雷,会显示出一个数字或者是一个空格子这表示一概方格为中心周围的把各方格子中总共有多少颗地雷,玩家需要进行判断继续游戏,若是地雷则玩家输了这盘游戏,这时玩家可以退出游戏或选择重新开始。
若玩家确定某个方格子底下是地雷,这是可以单击鼠标右键,不管是不是正确,这时会出现一个小旗子标志,同时剩余地雷数减一个。
游戏胜利后,系统会弹出对话框保存成绩可以记录胜利者的名字。
实现环境及工具简介系统开发平台:Eclipse1.7数据库管理系统软件:Oracle运行平台:windows XPJava开发包:jdk7.02总体设计总体设计:再设计扫雷游戏时,需要编写7个源文件:MineGame.java,MineArea.java,Block.java,BlockView.java,LayMines.java,ShowRecord.java,Record.java 除了这七个源文件外,还需要Java系统提供一些重要的类,如File,JButton和JLabel等类。
2.1 MineGame.java(主类):主要负责创建扫雷游戏主窗口,该文件有main方法,扫雷游戏从该类开始执行。
扫雷游戏Java源代码import java.awt.BorderLayout;import java.awt.Container;import java.awt.Font;import java.awt.GridLayout;import java.awt.Insets;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JPanel;import javax.swing.Timer;public class ScanLei1 extends JFrame implements ActionListener{ private static final long serialVersionUID = 1L;private Container contentPane;private JButton btn;private JButton[] btns;private JLabel b1;private JLabel b2;private JLabel b3;private Timer timer;private int row=9;private int col=9;private int bon=10;private int[][] a;private int b;private int[] a1;private JPanel p,p1,p2,p3;public ScanLei1(String title){super(title);contentPane=getContentPane();setSize(297,377);this.setBounds(400, 100, 400, 500);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);timer =new Timer(1000,(ActionListener) this);a = new int[row+2][col+2];initGUI();}public void initGUI(){p3=new JPanel();b=bon;JMenuBar menuBar=new JMenuBar();JMenu menu1=new JMenu("游戏");JMenu menu2=new JMenu("帮助");JMenuItem mi1=new JMenuItem("初级");JMenuItem mi2 = new JMenuItem("中级");JMenuItem mi3 =new JMenuItem("高级");mi1.addActionListener(this);menu1.add(mi1);mi2.addActionListener(this);menu1.add(mi2);mi3.addActionListener(this);menu1.add(mi3);menuBar.add(menu1);menuBar.add(menu2);p3.add(menuBar);b1=new JLabel(bon+"");a1=new int[bon];btn =new JButton("开始");btn.addActionListener(this);b2=new JLabel("0");b3=new JLabel("");btns=new JButton[row*col];p=new JPanel();p.setLayout(new BorderLayout());contentPane.add(p);p.add(p3,BorderLayout.NORTH);//combo=new JComboBox(new Object[]{"初级","中级","高级"} );//加监听/*combo.addItemListener(new ItemListener(){}});*/p1=new JPanel();//在那个位置//(( FlowLayout)p1.getLayout()).setAlignment( FlowLayout.RIGHT);p1.add(b1);p1.add(btn);p1.add(b2);p1.add(b3);p.add(p3,BorderLayout.NORTH);p.add(p1,BorderLayout.CENTER);p2=new JPanel();p2.setLayout(new GridLayout(row,col,0,0));for(int i=0;i<row*col;i++){btns[i]=new JButton("");btns[i].setMargin(new Insets(0,0,0,0));btns[i].setFont(new Font(null,Font.BOLD,25));btns[i].addActionListener(this);btns[i].addMouseListener(new NormoreMouseEvent());p2.add(btns[i]);}contentPane.add(p,BorderLayout.NORTH);contentPane.add(p2,BorderLayout.CENTER);}public void go(){setVisible(true);}public static void main(String[] args){new ScanLei1("扫雷").go();}public void out(int[][] a,JButton[] btns,ActionEvent e,int i,int x,int y){ int p=1;if(a[x][y]==0){a[x][y]=10;btns[i].setEnabled(false); //33for(int l=y-1;l<=y+1;l++){int m=x-1-1;int n=l-1;p=1;System.out.println(a[1][2]);if(n>-1&&n<col&&m>-1&&m<row){for(int q=0;q<row&&p==1;q++){//col-->row;if(((n+col*q)>=(m*col))&&((n+col*q)<(m+1)*col)){if(a[x-1][l]!=0&&a[x-1][l]!=10){btns[n+col*q].setText(a[x-1][l]+"");a[x-1][l]=10;btns[n+col*q].setEnabled(false);}else if(a[x-1][l]==0){//a[x-1][l]=10;btns[n+col*q].setEnabled(false);out(a,btns,e,n+col*q,x-1,l); ////55////a[x-1][l]=10;btns[n+col*q].setEnabled(false);}p=0;}}}p=1;m=x;if(n>-1&&n<col&&m>-1&&m<col){for(int q=0;q<row&&p==1;q++){if(((n+col*q)>=(m*col))&&((n+col*q)<(m+1)*col)){if(a[x+1][l]!=0&&a[x+1][l]!=10){btns[n+col*q].setText(a[x+1][l]+"");a[x+1][l]=10;btns[n+col*q].setEnabled(false);}else if(a[x+1][l]==0){out(a,btns,e,n+col*q,x+1,l);///55////a[x+1][l]=10;btns[n+col*q].setEnabled(false);}p=0;}}}}int m=x-1;int n=y-1-1;p=1;if(n>-1&&n<col&&m>-1&&m<col){for(int q=0;q<row&&p==1;q++){if(((n+col*q)>=(m*col))&&((n+col*q)<(m+1)*col)){if(a[x][y-1]!=0&&a[x][y-1]!=10){btns[n+col*q].setText(a[x][y-1]+"");a[x][y-1]=10;btns[n+col*q].setEnabled(false);}else if(a[x][y-1]==0){out(a,btns,e,n+col*q,x,y-1);a[x][y-1]=10;btns[n+col*q].setEnabled(false);}p=0;}}}p=1;m=x-1;n=y+1-1;if(n>-1&&n<col&&m>-1&&m<col){for(int q=0;q<row&&p==1;q++){if(((n+col*q)>=(m*col))&&((n+col*q)<(m+1)*col)){if(a[x][y+1]!=0&&a[x][y+1]!=10){btns[n+col*q].setText(a[x][y+1]+"");a[x][y+1]=10;btns[n+col*q].setEnabled(false);}else if(a[x][y+1]==0){out(a,btns,e,n+col*q,x,y+1);a[x][y+1]=10;btns[n+col*q].setEnabled(false);}p=0;}}}}}public void actionPerformed(ActionEvent e) {if(e.getActionCommand()=="初级"){row=9;col=9;bon=10;a1=new int[bon];b=bon;//setSize(297,377);a = new int[row+2][col+2];this.remove(p2);timer.stop();b1.setText("10");b2.setText("0");b3.setText("");btns=new JButton[row*col];p2=new JPanel();p2.setLayout(new GridLayout(row,col,0,0));for(int i=0;i<row*col;i++){btns[i]=new JButton(" ");btns[i].setMargin(new Insets(0,0,0,0));btns[i].setFont(new Font(null,Font.BOLD,25));btns[i].addActionListener(this);btns[i].addMouseListener(new NormoreMouseEvent());p2.add(btns[i]);}contentPane.add(p2,BorderLayout.CENTER);//setSize(297,377);this.pack();for(int i=0;i<row*col;i++){btns[i].setText(" ");btns[i].setEnabled(true);}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){a[i][j]=0;}}}else if(e.getActionCommand()=="中级"){row=16;col=16;bon=40;//setSize(33*col,33*row+80);a1=new int[bon];a = new int[row+2][col+2];b=bon;this.remove(p2);timer.stop();b1.setText("40");b2.setText("0");b3.setText("");btns=new JButton[row*col];p2=new JPanel();p2.setLayout(new GridLayout(row,col,0,0));for(int i=0;i<row*col;i++){btns[i]=new JButton(" ");btns[i].setMargin(new Insets(0,0,0,0));btns[i].setFont(new Font(null,Font.BOLD,25));btns[i].addActionListener(this);btns[i].addMouseListener(new NormoreMouseEvent());p2.add(btns[i]);}contentPane.add(p2,BorderLayout.CENTER);this.pack();//setSize(33*col,33*row+80);for(int i=0;i<row*col;i++){btns[i].setText("");btns[i].setEnabled(true);}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){a[i][j]=0;}}}else if(e.getActionCommand()=="高级"){row=16;col=32;bon=99;setSize(33*col,33*row+80);a1=new int[bon];a = new int[row+2][col+2];b=bon;this.remove(p2);timer.stop();b1.setText("99");b2.setText("0");b3.setText("");btns=new JButton[row*col];p2=new JPanel();p2.setLayout(new GridLayout(row,col,0,0));for(int i=0;i<row*col;i++){btns[i]=new JButton(" ");btns[i].setMargin(new Insets(0,0,0,0));btns[i].setFont(new Font(null,Font.BOLD,25));btns[i].addActionListener(this);btns[i].addMouseListener(new NormoreMouseEvent());p2.add(btns[i]);}contentPane.add(p2,BorderLayout.CENTER);//setSize(33*col,33*row+80);this.pack();for(int i=0;i<row*col;i++){btns[i].setText("");btns[i].setEnabled(true);}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){a[i][j]=0;}}}if(e.getSource()==btn){timer.start();b=bon;b3.setText("");//System.out.println(bon);//清空for(int i=0;i<row*col;i++){btns[i].setText("");btns[i].setEnabled(true);}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){a[i][j]=0;}}//产生随机数for(int i=0;i<bon;i++){ int p=1;int m=(int)(Math.random()*row*col);while(p==1){int l=1;int j;for( j=0;j<i&&l==1;j++){if(a1[j]==m){m=(int)(Math.random()*row*col);l=0;}}if(j==i){a1[i]=m;p=0;}}}b1.setText(bon+"");b2.setText("0");//布雷for(int i=0;i<bon;i++){int x=(a1[i]/col+1);int y=(a1[i]%col+1);a[x][y]=100;}for(int i=0;i<row+2;i++){for(int j=0;j<col+2;j++){if(i==0||j==0||i==row+1||j==col+1){a[i][j]=0;}}}for(int i=1;i<=row;i++){for(int j=1;j<=col;j++){if(a[i][j]!=100){for(int l=j-1;l<=j+1;l++){if(a[i-1][l]==100){a[i][j]++;}if(a[i+1][l]==100){a[i][j]++;}}if(a[i][j-1]==100){a[i][j]++;}if(a[i][j+1]==100){a[i][j]++;}}}}}if(e.getSource()==timer){String time=b2.getText().trim();int t=Integer.parseInt(time);//System.out.println(t);if(t>=600){timer.stop();}else{t++;b2.setText(t+"");}}for(int i=0;i<col*row;i++){if(btns[i].getText()!="★"){int x=i/col+1;int y=i%col+1;if(e.getSource()==btns[i]&&a[x][y]==100){btns[i].setText("★");btns[i].setEnabled(false);a[x][y]=10;for(int k=0;k<col*row;k++){int m1=k/col+1;int n1=k%col+1;if(a[m1][n1]!=10&&btns[k].getText()=="★"){btns[k].setText("*o*");}}for(int j=0;j<col*row;j++){int m=j/col+1;int n=j%col+1;if(a[m][n]==100){btns[j].setText("★");btns[j].setEnabled(false);b3.setText("你输了!!");}btns[j].setEnabled(false);a[m][n]=10;}timer.stop();}else if(e.getSource()==btns[i]){if(a[x][y]==0){out(a,btns,e,i,x,y);a[x][y]=10;btns[i].setEnabled(false);}if(a[x][y]!=0&&a[x][y]!=10){btns[i].setText(a[x][y]+"");btns[i].setEnabled(false);a[x][y]=10;}}}else if(btns[i].getText()=="★"){}}}class NormoreMouseEvent extends MouseAdapter{public void mouseClicked(MouseEvent e) {System.out.println(b);for(int i=0;i<col*row;i++){int x1=i/col+1;int y1=i%col+1;if(e.getSource()==btns[i]&&btns[i].getText()!="★"&&a[x1][y1]!=10){if(e.getButton()==MouseEvent.BUTTON3){btns[i].setText("★");b--;if(b==0){int flag=0;for(int j=0;j<col*row;j++){int x=j/col+1;int y=j%col+1;if(a[x][y]==100&&btns[j].getText()=="★"){flag++;}}if(flag==bon){timer.stop();b3.setText("你赢了!");}}b1.setText(b+"");}}elseif(e.getSource()==btns[i]&&btns[i].getText()=="★"&&a[x1][y1]!=-1){if(e.getButton()==MouseEvent.BUTTON3){btns[i].setText("");b++;if(b>bon){b1.setText(bon+"");}else{b1.setText(b+"");}btns[i].setEnabled(true);}}}}}}。
整个程序使用了4个类:Game 用于启动程序, 界面的布置,各种行列的算法。
ExtendButton 继承了Jbutton 用于新建button的各种属性ShowNum 监听到某个button后,计算出此button周围有几个雷,不同的雷对应不通的图片,类得到button上应加载的图片地址ViewReSet 此类用于新建一个窗口,用户输入自己想要的行、列、雷数,然后用新的行列雷数new 一个新的Gamebiaose dise1 dise2 dise3dise4 dise5 dise6 dise7dise8 dise lei biaoji/****************************************************************运行类创建游戏主窗体*/package com.dhl.saolei;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Container;import java.awt.Dimension;import java.awt.Font;import java.awt.GridLayout;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.InputEvent;import java.awt.event.KeyEvent;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JToolBar;import javax.swing.KeyStroke;import javax.swing.Timer;public class Game extends JFrame implements ActionListener{ private Container myContainer;private GridLayout myLayout;private JPanel myPanelMain;private JPanel myPanel;private JToolBar myTool;private JLabel time;private JLabel labelTime;private JLabel bombNum;private JLabel labelBombNum;private JMenuBar menuBar;private JMenu menuE, menuH;private JMenuItem menuItemCZ, menuItemSZ;private int numBomb, countTime, leaveBomb, numEnd;private int myRows, myColumns;private int xis, yis;private Timer timer;private ExtendButton[] myButton = null;//初始化窗体private void InitView() {//菜单初始化this.menuBar = new JMenuBar();this.menuE = new JMenu("菜单(E)");this.menuH = new JMenu("帮助(H)");this.menuItemCZ = new JMenuItem("重置");this.menuItemCZ.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK _C, InputEvent.CTRL_MASK));this.menuItemCZ.addActionListener(this);this.menuE.add(this.menuItemCZ);this.menuItemSZ = new JMenuItem("设置");this.menuItemCZ.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK _S, InputEvent.CTRL_MASK));this.menuItemSZ.addActionListener(this);this.menuE.add(this.menuItemSZ);this.menuBar.add(this.menuE);this.menuBar.add(this.menuH);setJMenuBar(this.menuBar);//时间信息初始化this.myTool = new JToolBar();this.myTool.setLayout(new GridLayout(1, 4));this.myTool.setFloatable(false);BorderLayout borderLayout = new BorderLayout();this.myPanelMain = new JPanel(borderLayout);belTime = new JLabel("时间:");this.time = new JLabel();this.time.setForeground(Color.RED);this.time.setFont(new Font("font", Font.PLAIN, 20));belBombNum = new JLabel("雷数:");this.bombNum = new JLabel();this.bombNum.setText(String.valueOf(this.numBomb));this.bombNum.setForeground(Color.RED);this.bombNum.setFont(new Font("font", Font.PLAIN, 20));this.myTool.add(belTime);this.myTool.add(this.time);this.myTool.add(belBombNum);this.myTool.add(this.bombNum);this.myPanelMain.add(this.myTool, borderLayout.NORTH);}// 初始化myButtonprivate void InitButton() {BorderLayout borderLayout = new BorderLayout();this.leaveBomb = this.numBomb;this.numEnd = (this.myRows * this.myColumns) - this.leaveBomb;this.myContainer = this.getContentPane();this.myLayout = new GridLayout(this.myRows, this.myColumns, 1, 1);this.myPanel = new JPanel();this.myPanel.setVisible(true);this.myPanel.setLayout(myLayout);this.myPanelMain.add(this.myPanel, borderLayout.CENTER);this.myContainer.add(this.myPanelMain);this.myButton = new ExtendButton[(this.myRows *this.myColumns)];for (int i = 0; i < (this.myRows * this.myColumns); i++) { this.myButton[i] = new ExtendButton();this.myButton[i].SetPostion(i);this.myButton[i].setIcon((new ShowNum(10)).getImageIcon());this.myButton[i].setButton_num(0);this.myButton[i].SetVisited(false);this.myButton[i].SetStatus(false);//设置右键监听标记雷this.myButton[i].addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent evt) {if ((evt.getModifiers() == InputEvent.BUTTON3_MASK)) {int n =((ExtendButton)evt.getSource()).getButton_num();if(n == 1) {if(!((ExtendButton)evt.getSource()).GetVisited()) {((ExtendButton)evt.getSource()).setButton_num(0);((ExtendButton)evt.getSource()).setIcon((newShowNum(10)).getImageIcon());leaveBomb++;bombNum.setText(String.valueOf(leaveBomb));}} else {if(!((ExtendButton)evt.getSource()).GetVisited()) {((ExtendButton)evt.getSource()).setButton_num(1);((ExtendButton)evt.getSource()).setIcon((newShowNum(11)).getImageIcon());leaveBomb--;bombNum.setText(String.valueOf(leaveBomb));}}}}});this.myPanel.add(this.myButton[i]);this.myButton[i].addActionListener(this);}System.gc();this.SetBomb(this.numBomb);show();//时钟设置int delay = 1000;// 创建一个监听事件ActionListener drawClock = new ActionListener(){public void actionPerformed(ActionEvent evt){countTime++;time.setText(String.valueOf(countTime));repaint();}};// 创建一个时间计数器,每一秒触发一次this.timer = new Timer(delay,drawClock);this.timer.start();}//重新初始化方法private void SetExtendButton() {for (int i = 0; i < (this.myRows * this.myColumns); i++) { this.myButton[i].SetVisited(false);this.myButton[i].SetStatus(false);this.myButton[i].setText(null);this.myButton[i].setIcon((new ShowNum(10)).getImageIcon());}this.SetBomb(numBomb);this.countTime = 0;this.timer.start();this.leaveBomb = numBomb;this.bombNum.setText(String.valueOf(this.numBomb));this.numEnd = (this.myRows * this.myColumns) - leaveBomb;}//布雷方法private void SetBomb(int count) {int counter = 0;int tempint;while(counter != count) {tempint = (int) (Math.random()*(this.myRows *this.myColumns));if(!this.myButton[tempint].GetStatus()) {this.myButton[tempint].SetStatus(true);counter++;}}}//显示雷得方法private void ShowBomb() {for(int i = 0; i < (this.myRows * this.myColumns); i++) { if(this.myButton[i].GetStatus()) {this.myButton[i].setIcon((newShowNum(9)).getImageIcon());}}}//监听点击扫雷方法private void CheckButton(ExtendButton TempButton) {if(TempButton.GetStatus()) {this.timer.stop();JOptionPane.showMessageDialog(null, "You Failed!", "Game",RMATION_MESSAGE);this.ShowBomb();int i = JOptionPane.showConfirmDialog(null, "是否要继续?", "消息", JOptionPane.YES_NO_OPTION);if(JOptionPane.YES_OPTION == i) {SetExtendButton();} else {this.dispose();}return;}int[] CircleNum = new int[8];int temp = 0;if(!TempButton.GetVisited()) {CircleNum[0] = TempButton.GetPostion() - this.myColumns- 1;CircleNum[0] = (CircleNum[0] < 0 || (CircleNum[0] + 1) % this.myColumns == 0) ? -1 : CircleNum[0];CircleNum[1] = TempButton.GetPostion() - this.myColumns;CircleNum[1] = (CircleNum[1] < 0) ? -1 : CircleNum[1];CircleNum[2] = TempButton.GetPostion() - this.myColumns+ 1;CircleNum[2] = (CircleNum[2] < 0 ||CircleNum[2] %this.myColumns == 0) ? -1 : CircleNum[2];CircleNum[3] = TempButton.GetPostion() - 1;CircleNum[3] = ((CircleNum[3] + 1) % this.myColumns == 0) ? -1 : CircleNum[3];CircleNum[4] = TempButton.GetPostion() + 1;CircleNum[4] = (CircleNum[4] % this.myColumns == 0) ? -1 : CircleNum[4];CircleNum[5] = TempButton.GetPostion() + this.myColumns -1;CircleNum[5] = (CircleNum[5] > (this.myRows* this.myColumns - 1) || (CircleNum[5] + 1) % this.myColumns == 0) ? -1 : CircleNum[5];CircleNum[6] = TempButton.GetPostion() + this.myColumns;CircleNum[6] = (CircleNum[6] > (this.myRows* this.myColumns - 1)) ? -1 : CircleNum[6];CircleNum[7] = TempButton.GetPostion() + this.myColumns +1;CircleNum[7] = (CircleNum[7] > (this.myRows* this.myColumns - 1) || CircleNum[7] % this.myColumns == 0) ? -1 : CircleNum[7];for (int i = 0; i < 8; i++) {if(CircleNum[i] != -1) {if(myButton[CircleNum[i]].GetStatus()&& !myButton[CircleNum[i]].GetVisited()) {temp++;}}}//显示button图片过程if(temp > 0) {TempButton.SetVisited(true);TempButton.setIcon((new ShowNum(temp)).getImageIcon());temp = 0;} else if(temp == 0) {TempButton.SetVisited(true);TempButton.setIcon((new ShowNum(0)).getImageIcon());for (int i = 0; i < 8; i++) {if(CircleNum[i] != -1&& !myButton[CircleNum[i]].GetVisited()) {CheckButton(myButton[CircleNum[i]]);}}}this.numEnd--;if(this.numEnd == 0) {this.timer.stop();JOptionPane.showMessageDialog(this, "恭喜你!", "消息", RMATION_MESSAGE);ShowBomb();}}}// 构造方法public Game() {Dimension dimension =Toolkit.getDefaultToolkit().getScreenSize();int x = (int) ((dimension.getWidth() - 400) / 2);int y = (int) ((dimension.getHeight() - 500) / 2);this.xis = 300;this.yis = 400;this.setBounds(x, y, this.xis, this.yis);this.setTitle("扫雷");this.numBomb = 10;this.myRows = 9;this.myColumns = 9;this.InitView();this.InitButton();this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);}public Game(int row, int column, int numbomb) {Dimension dimension =Toolkit.getDefaultToolkit().getScreenSize();int x = (int) ((dimension.getWidth() - 400) / 2);int y = (int) ((dimension.getHeight() - 500) / 2);this.xis = 310 * column /9;this.yis = 300 * row / 9 + 100;this.setBounds(x, y, this.xis, this.yis);this.setTitle("扫雷");this.myRows = row;this.myColumns = column;this.numBomb = numbomb;this.InitView();this.InitButton();this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);}//监听方法public void actionPerformed(ActionEvent e) {//对(this.myRows * this.myColumns)个button的监听进行处理for (int i = 0; i < (this.myRows * this.myColumns); i++) { if(e.getSource() == myButton[i]) {CheckButton((ExtendButton) e.getSource());}}//重置按钮监听if(e.getSource() == menuItemCZ) {SetExtendButton();//设置按钮进行监听} else if(e.getSource() == menuItemSZ) {new ViewReSet(this.myRows, this.myColumns, this.numBomb);this.dispose();}}public static void main(String[] args) {new Game();}}/***********************************************************创建一个button的实体类*/package com.dhl.saolei;import javax.swing.JButton;public class ExtendButton extends JButton {private int Button_pos;private int Button_num;private boolean Button_Status;private boolean Button_Visited;public int getButton_num() {return Button_num;}public void setButton_num(int button_num) {this.Button_num = button_num;}public int SetPostion(int pos) {this.Button_pos = (pos >= 0) ? pos : 0;return this.Button_pos;}public int GetPostion() {return this.Button_pos;}public boolean SetStatus(boolean sta) {this.Button_Status = sta;return this.Button_Status;}public boolean GetStatus() {return this.Button_Status;}public boolean SetVisited(boolean vis) {this.Button_Visited = vis;return this.Button_Visited;}public boolean GetVisited() {return this.Button_Visited;}}/*******************************************************************设置button显示图片*/package com.dhl.saolei;import java.awt.Image;import javax.swing.ImageIcon;public class ShowNum {private int num;public ShowNum(int n) {this.num = n;}public ImageIcon getImageIcon() {ImageIcon imageIcon;switch (num) {case 0:imageIcon = new ImageIcon("./class/images/dise.jpg");break;case 1:imageIcon = new ImageIcon("./class/images/dise1.jpg");break;case 2:imageIcon = new ImageIcon("./class/images/dise2.jpg");break;case 3:imageIcon = new ImageIcon("./class/images/dise3.jpg");break;case 4:imageIcon = new ImageIcon("./class/images/dise4.jpg");break;case 5:imageIcon = new ImageIcon("./class/images/dise5.jpg");break;case 6:imageIcon = new ImageIcon("./class/images/dise6.jpg");break;case 7:imageIcon = new ImageIcon("./class/images/dise7.jpg");break;case 8:imageIcon = new ImageIcon("./class/images/dise8.jpg");break;case 9:imageIcon = new ImageIcon("./class/images/lei.jpg");break;case 10:imageIcon = new ImageIcon("./class/images/biaose.jpg");break;case 11:imageIcon = new ImageIcon("./class/images/leibj.jpg");break;default:imageIcon = new ImageIcon("./class/images/dise.jpg");break;}return imageIcon;}}/******************************************************************* *创建一个新窗口,输入新的行、列、雷数,然后用新数据重新new一个Game窗口*/package com.dhl.saolei;import java.awt.Container;import java.awt.Dimension;import java.awt.GridBagConstraints;import java.awt.GridBagLayout;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JDialog;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JTextField;public class ViewReSet extends JDialog implements ActionListener{ private JFrame frame = null;private JPanel myPanel = null;private JLabel myLabel = null;private JLabel myLabelRow = null;private JLabel myLabelColum = null;private JLabel myLabelBombNum = null;private JTextField myFieldRow = null;private JTextField myFieldColum = null;private JTextField myFieldBombNum = null;private JButton buttonOK = null;private JButton buttonReset = null;private int row;private int column;private int bombNum;private int [] myrcb = new int [3];private void createView(){Container container = this.getContentPane();this.myPanel = new JPanel(new GridBagLayout());container.add(this.myPanel);GridBagConstraints gbc = new GridBagConstraints();gbc.gridx = 1;gbc.gridy = 0;this.myLabel = new JLabel("窗口行列设置");this.myPanel.add(this.myLabel, gbc);gbc.gridx = 0;gbc.gridy = 1;this.myLabelRow = new JLabel("行数:");this.myPanel.add(this.myLabelRow, gbc);gbc.gridx = 1;gbc.gridy = 1;this.myFieldRow = new JTextField(10);this.myPanel.add(this.myFieldRow, gbc);gbc.gridx = 0;gbc.gridy = 2;this.myLabelColum = new JLabel("列数:");this.myPanel.add(this.myLabelColum, gbc);gbc.gridx = 1;gbc.gridy = 2;this.myFieldColum = new JTextField(10);this.myPanel.add(this.myFieldColum, gbc);gbc.gridx = 0;gbc.gridy = 3;this.myLabelBombNum = new JLabel("雷数:");this.myPanel.add(this.myLabelBombNum, gbc);gbc.gridx = 1;gbc.gridy = 3;this.myFieldBombNum = new JTextField(10);this.myPanel.add(this.myFieldBombNum, gbc);JPanel btnPanel = new JPanel();btnPanel.setOpaque(false);this.buttonOK = new JButton("确定");this.buttonOK.addActionListener(this);btnPanel.add(this.buttonOK);this.buttonReset = new JButton("重置");this.buttonReset.addActionListener(this);btnPanel.add(this.buttonReset);gbc.gridx = 1;gbc.gridy = 4;this.myPanel.add(btnPanel, gbc);this.setTitle("设置");this.setDefaultCloseOperation(this.DISPOSE_ON_CLOSE);}public ViewReSet(int r, int c, int b) {Dimension dimension =Toolkit.getDefaultToolkit().getScreenSize();int xAxis = (int) ((dimension.getWidth() - 300) / 2);int yAyis = (int) ((dimension.getHeight() - 200) / 2);this.setBounds(xAxis, yAyis, 300, 200);this.myrcb[0] = r;this.myrcb[1] = c;this.myrcb[2] = b;this.createView();this.setVisible(true);}public void actionPerformed(ActionEvent e) {if(e.getSource() == this.buttonReset) {this.myFieldRow.setText(null);this.myFieldColum.setText(null);} else if(e.getSource() == this.buttonOK) {String r, c, b;r = this.myFieldRow.getText();if(r.length() > 0) {this.row = Integer.parseInt(r);} else {this.row = this.myrcb[0];}c = this.myFieldColum.getText();if(c.length() > 0) {this.column = Integer.parseInt(c);} else {this.column = this.myrcb[1];}b = this.myFieldBombNum.getText();if(b.length() > 0) {this.bombNum =Integer.parseInt(this.myFieldBombNum.getText());} else {this.bombNum = this.myrcb[2];}new Game(this.row, this.column, this.bombNum);this.dispose();}}}。