跟我学Java Swing之游戏设计(2)

文章来源:电脑爱好者 作者:张剑

  还记得《偷天换日》中精灵般穿梭在好莱坞车流中的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[i] = new JButton("Kyodai");
  dots[i].setActionCommand("" + i);
  contentPanel.add(dots[i]);
  dots[i].addActionListener(this);
}

  千万别忘记了在循环体中写上dots[i] = 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())方法将取得的事件名称转化为整数,后面的代码就将这个整数还原成行和列的信息。

  好了,现在运行程序,然后点击每个按钮,看看是否会出现如右图的对话框?

  注意哦,我们的下标是从0开始的。本期程序源代码(点击下载)。

 在Swing中使用图片

  目前我们已经解决了用户操作的问题。为了让界面美观起来,我们需要使用图片来代替文字。有时间和耐心的朋友可以自己做个性图片,只是要注意保持每张图片大小一致,否则就太难看啦。想省事的话也可以直接使用下载包中提供的图片。

  在Swing中,可以使用setIcon(Image image)方法来为JButton设置图片,其中的参数image就是我们要设置的图片对象,这个对象有多种方法可以得到:

  ·使用Toolkit类来获得:
    image = Toolkit.getDefaultToolkit().getImage(url);
   ·使用ImageIcon类的getImage()方法来获得:
  
  image = new ImageIcon(getClass().getResource(filename)).getImage();

  我们这里选用第一种方法。为了方便今后再次获得Image对象,我们可以将此写为一个函数:

Image getImage(String filename){
  URLClassLoader urlLoader = (URLClassLoader) this.getClass().getClassLoader();
  URL url = null;
  Image image = null;
  url = urlLoader.findResource(filename);
  image = Toolkit.getDefaultToolkit().getImage(url);
  return image;
}

  有了这个函数之后,以后再要用到图片就方便多了,不是吗?

  图片现在已经有了,那么我们就可以将源代码包中Map.Java中的地图信息用图片的形式表现出来了。由于此段代码是关于游戏的算法代码,因此不再列举代码,在这里大致解释一下具体是怎么做的吧!在Map.Java中,我们使用了二维数组map[][]来保存图片信息,同时,我们也使用了一维数组images[]来保存每一个图片对象,map中的每一个元素都有一个值,这个值不仅表明了在游戏界面中按钮对应的值,也表明了这个按钮使用images[]数组中图片的编号,程序运行界面便漂亮许多。

  小结

  今天我们介绍了Swing中JButton控件。对于大多数Swing控件来说,JButton的用法一样可以照搬过去。别小看这个JButton,当你能够很好地掌握它的时候,你的Swing功底就已经提升一个台阶了。此外,我们也学会了在Java中加载图片文件的两种方法。最后,我们还将以上的两部分内容结合在一起创造出了漂亮的游戏界面。虽然我没有在这里写出完整的代码,但相信大家参考我的源程序,经过自己的努力,一定能够达到目标。如果遇到解决不了的问题,可以通过leftmoon@163.com信箱与我联系。

  不知道大家对今天的内容感觉到满意吗?精彩还在后面,大家要继续光顾我们的咖啡馆哦!

(0)

相关推荐

  • Java基于swing实现的弹球游戏代码

    本文实例讲述了Java基于swing实现的弹球游戏代码.分享给大家供大家参考. 主要功能代码如下: 复制代码 代码如下: package Game; import java.awt.Graphics; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Random;

  • 经典再现 基于JAVA平台开发坦克大战游戏

    一.需求描述  1.功能性需求 在功能需求分析阶段,我们的主要任务是指定系统必须提供哪些服务,定义软件完成哪些功能,提供给那些人使用,功能需求是软件开发的一项基本需求,是需求分析必不可少的一部分.坦克大战是一款经典游戏了,本游戏学习了一些前辈们的经验,整体来说讲,游戏分为敌我双方,主要参与战斗的坦克有玩家控制,敌人坦克可以智能随机出现在屏幕上,并且移动,发射一定数量的子弹:玩家可以在规定的区域内随意移动坦克,当有子弹击中玩家时,玩家死亡,游戏结束:敌人坦克智能运行,敌方坦克由于需要具有一定智能性

  • java基于swing实现的五子棋游戏代码

    本文实例讲述了java基于swing实现的五子棋游戏代码.分享给大家供大家参考. 主要功能代码如下: 复制代码 代码如下: import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Main extends JFrame implements ActionListener{         private static final long serialVersionUID = 1L;      

  • 跟我学Java Swing之游戏设计(1)

    文章来源:电脑爱好者 作者:张剑 谁知道通天的巴比伦塔耗费了多少沙石?又有谁知道罗马的建成经历了多少个日夜?我们惟一知道的是,没有一块块砖石的垒砌,就没有蜿蜒万里的长城;没有巨石和黏土的堆集,就没有亘古不变的金字塔.由此可见,基础知识的准备对于我们学习任何事物都至关重要,那么,就让我们从认识Swing的一些基础功能开始,启动我们建造罗马的伟大工程吧! 前言 Java咖啡馆已经开张不少时日了,如果你已经喜欢上了Java这杯咖啡的味道,那么记得常来哦.这一次,我们为大家准备了一大杯香浓的咖啡--将以

  • java实现五子棋小游戏

    java实现五子棋小游戏 package Gomoku; import java.awt.Toolkit; import javax.swing.JFrame; public class GomokuFrame extends JFrame { //定义一个操作面板 OperatorPane op=null; public GomokuFrame() { //设置名称 this.setTitle("五子棋"); //设置窗口大小 this.setSize(510,510); //设置窗

  • Java完美实现2048小游戏

    完美地模仿了2048游戏,是根据网友的一个2048改的. Block.java import javax.swing.*; import java.awt.*; public class Block extends JLabel { private int value; public Block() { value = 0;//初始化值为0 setFont(new Font("font", Font.PLAIN, 40));//设定字体 setBackground(Color.gray

  • java实现的简单猜数字游戏代码

    本文实例讲述了java实现的简单猜数字游戏代码.分享给大家供大家参考. 具体代码如下: 复制代码 代码如下: import java.util.InputMismatchException; import java.util.Scanner; public class Main {         public static void main(String[] args) {                 // 产生一个随机数                 int number = (in

  • java编写贪吃蛇小游戏

    废话不多说,直接奉上代码: Frame.java package snake; import java.awt.Graphics; import java.awt.Menu; import java.awt.MenuBar; import java.awt.MenuItem; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import

  • Java制作智能拼图游戏原理及代码

    今天突发奇想,想做一个智能拼图游戏来给哄女友. 需要实现这些功能 第一图片自定义 第二宫格自定义,当然我一开始就想的是3*3 4*4 5*5,没有使用3*5这样的宫格. 第三要实现自动拼图的功能,相信大家知道女人耍游戏都不是很厉害,所以这个自动拼图功能得有. 其他什么暂停.排行就不写了! 现在重点问题出来了 要实现自动拼图功能似乎要求有点高哦!计算机有可不能像人一样只能: 先追究下本质 拼图游戏其实就是排列问题: 排列有这么一个定义:在一个1,2,...,n的排列中,如果一对数的前后位置与大小顺

  • Java基于Swing实现的打猎射击游戏代码

    本文实例讲述了Java基于Swing实现的打猎射击游戏代码.分享给大家供大家参考. 具体实现代码如下: 复制代码 代码如下: package Game; import java.awt.Graphics; import java.awt.Image; import javax.swing.JPanel; public class BackgroundPanel extends JPanel {         private static final long serialVersionUID

随机推荐