您的位置:首页 > 其它

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

2012-01-08 12:06 531 查看
我看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.png

b.png

c.png

0.png

1.png


2.png

3.png

4.png

5.png

6.png


7.png

8.png


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

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

以后犯得就会少一点了。

我把这一话的资源已经上传了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: