正在阅读:跟我学Java Swing之游戏设计(3)跟我学Java Swing之游戏设计(3)

2005-10-26 10:04 出处: 作者:张剑 责任编辑:xietaoming

  让文字活起来

  渴望无限,创造无限。如果能把计分和计时功能做成动画,一定会更加生动。最简单的做法就是让数字依次变化,比如说时间,我们可以每隔1秒钟就显示一次数值,比如说上面的代码,我们可以简单改为:

for (int i = 1000; i < 2000; i++) {
  g2.setBackground(new Color(111, 146, 212));
  g2.clearRect(0, 0, d.width, d.height); // 清除当前绘图区域
  g2.setColor(Color.yellow);
  g2.drawString("" + i, 16, 40);
  try {
    Thread.sleep(1000); // 延时 1 秒钟
  } catch (InterruptedException ex) {
  }
}

  当你执行以上代码以后便会知道,上面的代码实际上有问题!我们使用了Thread.sleep(1000)来让程序进行延时,每当执行Thread.sleep()的时候,程序会进入休眠状态,不响应其他任何操作,就连显示也不会更新,所以也就无从显示动画效果了。

  线程(Thread)是惟一的解决方法,它可以让程序在同一个时刻完成两件或者两件以上的事情。想让你的程序支持线程,你可以选择以下两种方法的任意一种:

①public class Clock extends Thread
②public class Clock implements Runnable

  第一种方法要求你的程序继承Thread类,可是,如果继承Thread类之后,我们就没有办法再继承JPanel了,因为Java不支持多重继承,如果不能继承JPanel,那么paint(Graphics g)也没有用武之地了。而第二种方法只要求你实现Runnable接口,而Java允许一个类实现多个接口,所以我们应该选择第二种方法。

  首先需要把Clock的声明改成public class Clock extends JPanel implements Runnable,然后添加public void run() {  }

  上面是实现Runnable接口的最基本的构架。有的时候,为了让线程能够具备开始和停止的功能,我们还得再扩充一下。首先是线程的开始:

public void start() {
  startTime = System.currentTimeMillis();
  thread = new Thread(this);
  thread.start();
}

  这里我们使用了System.currentTimeMillis()来获得开始时的系统时间,以便于以后计算用户的游戏时间。

  然后是运行的过程:

public void run() {
  Thread currentThread = Thread.currentThread();
  while (thread == currentThread) {
    long time = System.currentTimeMillis();
    usedTime = time - startTime;
    try {
      repaint();
      thread.sleep(100);
    }
    catch (InterruptedException ex) {
    }
  }
}

  第一句话Thread currentThread = Thread.currentThread();获得系统当前的线程,然后在循环中进行判断是否为当前线程,这在在线程比较多而且线程之间的依赖性比较强的情况下非常有必要。repaint() 是AWT/Swing控件的方法,它会自动调用paint(Graphics g)方法以便重新绘制显示区域。最后,我们使用了thread.sleep(100)来让程序每隔0.1秒运行一次。由于thread.sleep()方法会抛出异常,所以我们还需要捕获异常。

  由于paint(Graphics g)每次显示的内容都会不同,因此,我们需要使用一个全局全量usedTime来记录当前的时间,在输出的时候,我们应写成:

  g2.drawString("TimE:" + getTime(), 16, 40);

  其实getTime()方法是我们自己写的,其作用是获得用户当前使用的时间,并将时间格式化后传出。最后,别忘记了在我们的主程序中调用start()方法,如:

Clock clock = new Clock();
clock.start();
actionPanel.add(clock);

  小方糖

  Thread的前世今生

  最早的Thread提供了Thread.start() 、Thread.pause()/Thread.resume() 、Thread.stop() 这三个方法来完成线程的开始、暂停和结束功能,然而,在后来的JDK中,Sun却不推荐使用pause()/resume()和stop()方法,理由是pause()和stop()方法在某些场合会让程序进入死锁状态,因此,在你的程序中,假如你使用了Thread的以上几种方法,编译的时候编译器会告诉你

"xxx.java": stop() in java.lang.Thread has been deprecated at line xx, column xx

  这时候你就要注意了!

  小结

  今天我们学习了使用Graphics/Graphics2D来满足自己特殊的需要,再也不需要看控件的脸色了。同时,我们也知道了如何使用线程来让程序同时进行多个操作,并且结合了以上两点来实现计时功能。但是我没有在这里完成计分功能,就把这当作留给大家的小小作业吧!

键盘也能翻页,试试“← →”键

关注我们

最新资讯离线随时看 聊天吐槽赢奖品