扫雷游戏制作全过程02 之 JButton 弯路

来源:互联网 发布:android ble 大数据 编辑:程序博客网 时间:2024/05/16 08:24

我看JButton(用了前文00的感官)长得很好看,于是决定用一个JButton来代表一个地雷块。而此时完全没有考虑标记地雷和判输判赢的实现。

首先在面板上生成width*height个JButton,生成之时通过查询mine[][]数组来为JButton的mine属性赋值。然后监听点击事件,如果被点击,则打开该块

(其实是切换JButton的背景图片)。

这是MyButton类:

class MyButton extends JButton{private boolean is_mine = false;  private int status = 0;public MyButton(){this.setLayout(null);setIcon(new ImageIcon("a.png"));setMargin(new Insets(0,0,0,0));setIconTextGap(0);setBorderPainted(false);setBorder(null);setText(null);setRolloverIcon(new ImageIcon("b.png"));//setPressedIcon(new ImageIcon("c.png"));                // setSelectedIcon(new ImageIcon("d.png"));this.addActionListener(new ActionListener(){    public void actionPerformed(ActionEvent event)    {                         digOut();    }});}public void  beMarked()        {   this.setIcon(new ImageIcon("beMarked.png"));}         public void digOut(){     switch(status) {    case -1:  this.setIcon(new ImageIcon("c.png"));  //setRolloverIcon(new ImageIcon("c.png"));break;    case 0:  this.setIcon(new ImageIcon("0.png"));  //setRolloverIcon(new ImageIcon("0.png"));break;    case 1:  this.setIcon(new ImageIcon("1.png"));  //setRolloverIcon(new ImageIcon("1.png"));break;    case 2:  this.setIcon(new ImageIcon("2.png"));  //setRolloverIcon(new ImageIcon("2.png"));break;    case 3:  this.setIcon(new ImageIcon("3.png"));  //setRolloverIcon(new ImageIcon("3.png"));break;    case 4:  this.setIcon(new ImageIcon("4.png"));  //setRolloverIcon(new ImageIcon("4.png"));break;    case 5:  this.setIcon(new ImageIcon("5.png"));  //setRolloverIcon(new ImageIcon("5.png"));break;    case 6:  this.setIcon(new ImageIcon("6.png"));  //setRolloverIcon(new ImageIcon("6.png"));break;    case 7:  this.setIcon(new ImageIcon("7.png"));  //setRolloverIcon(new ImageIcon("7.png"));break;    case 8:  this.setIcon(new ImageIcon("8.png"));  //setRolloverIcon(new ImageIcon("8.png"));break;         }}public void setStatus(int copy_status){status = copy_status;}public boolean getIsMine(){    return is_mine;}}
生成地雷的Mine类多添加了一个方法getMineByLocation()

class Mine{//雷区的长和宽及雷的个数final int width = 5;final int height = 4;final int mine_num = 6;//为了生成雷区方便private int[][] mine= new int[height+2][width+2];public Mine(){createMine();initMine();}public void createMine(){int num = 0;int[] x = new int[mine_num];int[] y = new int[mine_num];//用于判断是否重复boolean mark = true;while(num<mine_num){x[num] = (int)(Math.random()*(height-1))+1;y[num] = (int)(Math.random()*(width-1))+1;mark = true;for(int i=0;i<num;i++){if(x[num]==x[i]&&y[num]==y[i]) mark = false;}  if(mark)num++;}//布雷for(int i=0;i<mine_num;i++){   mine[x[i]][y[i]] = -1;}}public void initMine(){   int mine_around = 0;   for(int i=1;i<=height;i++)   { for(int j=1;j<=width;j++) {if(mine[i][j]!=-1){  for(int k=i-1;k<=i+1;k++)for(int l=j-1;l<=j+1;l++)  if(mine[k][l]==-1) mine_around++;  mine[i][j]=mine_around;  mine_around = 0;} }   }}/*新添加了一个方法,生成M也Button时用到*/public int getMineByLocation(int copy_x,int copy_y){  return mine[copy_x][copy_y];}public int getWidth(){return width;}public int getHeight(){return height;}}

主要的控制类为MyPanel

class MyPanel extends JPanel{        private MyButton button[];public MyPanel(){    setSize(850,700);    Mine mine = new Mine();button = new MyButton[mine.getWidth()*mine.getHeight()];for(int i=0;i<20;i++){   button[i] = new MyButton();   add(button[i]);   /*因为生成的地雷数组有空边界,而初始化并不显示该边界*/   button[i].setStatus( mine.getMineByLocation(i%mine.width+1,i/mine.width+1));}                try{  UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");  SwingUtilities.updateComponentTreeUI(MyPanel.this);}catch(Exception e) { e.printStackTrace(); }}}

最为关键的就是button[i].setStatus( mine.getMineByLocation(i%mine.width+1,i/mine.width+1));将Mine与JButton联系了起来。

下面给一个用来测试的类

import javax.swing.*;import java.awt.*;import java.awt.event.*;public class PlayMine{    public static void main(String[] args)    {JFrame frame = new MyFrame();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        frame.setVisible(true);    }}class MyFrame extends JFrame{public MyFrame(){    setTitle("移动");    setSize(850,700);            JPanel panel = new MyPanel();    add(panel);    this.setFocusable(true);}}
运行PlayMine就OK了。对了一定要记得把图片和类文件放在同一层的目录下!

a.pngb.pngc.png0.png1.png

2.png3.png4.png5.png6.png


7.png8.png

当时写到这里还是很happy的,可是正要继续的时候,要开始做标记了,发现问题来了。出在了JButton上。


这个阶段是一个犯错的阶段,警示自己以后着手写软件前一定要先想一想,而不是直接上手。不过亲身犯一次这样的错,我想同样的错误

以后犯得就会少一点了。

我把这一话的资源已经上传了。