文章来源:电脑喜好者 作者:张剑</p> 还记得《偷天换日》中精灵般穿越在好莱坞车流中的Minicooper吗?马克·沃尔伯格和莎莉·赛隆就是驾驶着它在仇人的鼻子底下运走了价值千万的黄金。可是,假设如今将一辆无法飞驰的Minicooper躯壳放在你的面前,你会如何对待它?它还是那个游走自如的精灵吗?今天,就让我们一点一点地为这辆Minicooper组装上零件,让它跑起来。 前言
从本期开端,我们为大家提供完好的游戏源代码(点击下载)。Java咖啡馆倡导大家理论与理论并重,我们在连载中将给大家介绍关键技术以及实现思路,朋友们自行结合文章阅读源代码,好比一边读报一边喝咖啡,这才是滴滴香浓意犹未尽。 游戏规划
“连连看”属于一款二维战棋类游戏,要设计棋盘类的游戏,GridLayout应该是不二之选。如今让我们一起来看看GridLayout的构造函数:
·GridLayout():默认的情况下,将规划区域划分为1*1的大小
·GridLayout(int rows,int cols):指定规划区域横向和纵向的格子数
·GridLayout(int rows,int cols,int hgap,int vgap):同上,并且还指定了每个格子之间的横向间距hgap和纵向间距vgap
千万别让这三个构造函数把你给吓住了,其实只要你喜欢,完全可以放心大胆地使用其中的任何一个,就算不小心用“错”了,以后也有办法停止调整。唯一需要注意的是,GridLayout在添加控件时,默认顺序是从左上方向右下方依次添加的。
如今让我们来确定游戏的格子数目。终究多少格子比较适宜呢?太少会降低游戏的难度,太多又会形成视觉影响。所以,我们应该通过一对常量来表示,将来即便要修改,也是举手之劳。
在Java中,常量的定义需要写成public final static的形式,假设我们规定游戏的棋盘在横向有8个格子,纵向也有8个格子,那么,我们应该这样定义:
public final static int ROW = 8;
public final static int COLUMN = 8;
然后,我们使用GridLayout的第二种构造函数来创建规划:
GridLayout gridLayout = new GridLayout(ROW, COLUMN);
最后,我们还需要将游戏区(contentPanel)的规划改为上述规划:
contentPanel.setLayout(gridLayout);
假设你此时编译并运行程序的话,你可能会奇怪:界面怎么没有发生任何改变,是不是哪出错了?虽然我们指定了规划,可是什么控件也没有添加,当然就看不出变化。如今让我们一起在规划上添加按钮吧:
for (int i = 0; i < ROW * COLUMN; i++) {
JButton button = new JButton("Kyodai");
contentPanel.add(button);
}
再运行程序试试,是不是和我的一样(见图1)?
巧用JButton做文章
JButton是一个按钮控件,它也是Swing中普通得不能再普通的控件了,虽然如此,我们还是需要花费一点功夫来理解和使用它,因为当你可以熟练使用JButton后,你会发现其他的Swing控件也是如此的类似。
假设你将方才写好的程序拿来运行,你会发现:游戏区的按钮总是排得满满的,这对实际游戏的操作非常不便,所以,我们得想办法让一部分格子空出来。GridLayout规划什么都好,就是在添加控件的时候不能跳过某一个格子,这下可怎么办呢?
其实这也不难,既然GridLayout不让跳过,假设我们让某个格子内添加的控件与GridLayout规划的背景融为一体,这样在视觉上就到达了一致的效果。此外,假设他人在无意中点击到这个格子上,按钮仍然就会原形毕露,我们还得想办法让按钮不能被点击,这就需要用到JButton的setEnabled()方法。最后,对于可以点击的按钮,当它们被点击时,我们还得要区分出来终究是哪一个按钮被点击了。
在上一次实现“关于”功能的时候,我们使用了e.getSource()方法来判断鼠标点击事件产生的源,然而,那只对已经命名好了的控件比较有效。这里,使用数组表示按钮无疑是最好的方法了,首先让我们将上面的代码修改一下:
JButton[] dots = new JButton[ROW * COLUMN];
for (int i = 0; i < ROW * COLUMN; i++) {
dots = new JButton("Kyodai");
dots.setActionCommand("" + i);
contentPanel.add(dots);
dots.addActionListener(this);
}
千万别忘记了在循环体中写上dots = new JButton("Kyodai"),虽然在前面定义、使用了dots组数,然而,这仅仅只是告诉程序我们需要使用一些JButton,但是,这些JButton却仍然没有被初始化。同时,我们不只使用setActionCommand()为按钮制定了事件名称,还使用了addActionListener()方法为每个按钮加上了事件响应处置。
关于事件响应的代码,我们可以在原来actionPerformed()事件代码的后面添加:
if (e.getSource() instanceof JButton) {
JButton button = (JButton) e.getSource();
int offset = Integer.parseInt(button.getActionCommand());
int row, col;
row = Math.round(offset / COLUMN);
col = offset - row * COLUMN;
JOptionPane.showMessageDialog(this,"ROW="+row+",COL="
+ col, "按钮", JOptionPane.INFORMATION_MESSAGE);
}
在上面的代码中,e.getSource() instanceof JButton用来判断产生的事件是否是由JButton型的控件产生的,然后又将产惹事件源的控件停止强迫型类转换,再使用Integer.parseInt(button.getActionCommand())方法将获得的事件名称转化为整数,后面的代码就将这个整数复原成行和列的信息。
好了,如今运行程序,然后点击每个按钮,看看是否会呈现如右图的对话框?