,Java   工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛,Java
您的位置:软件 > 开发者网络 > 开发工具 > Java > 正文
JBuilder 2005开发Applet游戏全接触
[文章信息]
作者:陈雄华
时间:2005-02-22
出处:天极网
责任编辑:方舟
[文章导读]
本文拟通过一个耳熟能详的指法练习游戏讲解如何在JBuilder 2005下开发Applet应用程序
advertisement
热点推荐
· 深入探讨SQL Server 2000对XML的支持
· Swing(空)
· 3DS Stodio Max 宝典
· 中小企业服务器配置方案--前 言
· 中小企业服务器配置方案--代理接入服务器(3)
[正文]

上一页  1 2 3 4 5 6 7  下一页

  控制游戏

  至此,我们已经完成了Applet主要功能的开发,剩下的工作是如何通过按钮控制游戏。在编写控制代码之前,先为开始/暂停按钮(jButton1)和停止按钮(jButton2) 装饰一下,再编写控制代码。

  1、为按钮添加图标

  需要准备3张按钮的图标,图标为gif格式,尺寸大小为25×24象素。

  ·:jButton1在结束和暂停状态的图标,命名为start.gif。

  ·:jButton1在游戏处于运行状态的图标,命名为pause.gif。

  ·:jButton2的图标,命名为stop.gif。当游戏处于暂停或运行状态时,jButton2才被激活。

  将这些文件放置在TypeCharApplet.java源文件的目录下,即<工程根目录>/src/game目录下。

  下面的代码使用java.awt.ImageIcon引用这3个图标,并在jbInit()中将图标显示到按钮上,如下所示:

  代码清单 7 定义3个图标变量

1. …
2. public class TypeTrainApplet extends JApplet {
3.  …
4.  ImageIcon startIcon = new ImageIcon(TypeTrainApplet.class.getResource("start.gif"));
5.  ImageIcon pauseIcon = new ImageIcon(TypeTrainApplet.class.getResource("pause.gif"));
6.  ImageIcon stopIcon = new ImageIcon(TypeTrainApplet.class.getResource("stop.gif"));

7.  …
8.  private void jbInit() throws Exception {
9.   …
10.   jButton1.setIcon(startIcon);//设置开始按钮的图标
11.   jButton2.setIcon(stopIcon);//设置停止按钮的图标
12.   jButton2.setEnabled(false);//将停止按钮图标置为非激活态

13.   …
14.  }
15. }

  第4~6用前面所述的图片初始化3个图标变量,其中TypeTrainApplet.class.getResource()方法以TypeTrainApplet.class所在目录为相对目录,查询资源文件。

  第10~11行分别将开始和结束图标显示到对应的按钮上,当用户点击开始按钮后,才将jButton1的图标切换为暂停的图标pauseIcon。

  2、通过按钮事件控制游戏

  由于字母下落线程通过监测statusCode的值决定结束或暂停,所以我们仅需要通过按钮事件更改这个控制变量就可以达到控制游戏的目的了。

  首先,我们打开TypeTrainApplet.java切换到Design的UI设计界面中,双击jButton1按钮,JBuilder自动为jButton1添加一个按钮点击事件监听器,并切换到Source视图中,将光标定位到事件处理方法处,我们在方法中添加以下粗体的代码:

  代码清单 8 开始/暂停按钮事件处理方法

1. …
2. public class TypeTrainApplet extends JApplet {
3.  …
4.  public void jButton1_actionPerformed(ActionEvent e) {
5.   if (statusCode == 0) { //从结束->开始
6.    resetGame();
7.    statusCode = 1;
8.    colWidth = canvas.getWidth() / columnCount;
9.    //实例化字母下落线程产生器
10.   GenerateDropThread gdThread = new GenerateDropThread();
11.   gdThread.start();//产生器启动
12.   jButton1.setIcon(pauseIcon);//切换为暂停的图标
13.   jButton2.setEnabled(true);//停止按钮激活
14.  } else if (statusCode == 1) { //从运行->暂停
15.   statusCode = 2;
16.   jButton1.setIcon(startIcon);
17.  } else { //从暂停->运行
18.   statusCode = 1;
19.   jButton1.setIcon(pauseIcon);
20.   synchronized (canvas) {//通过canvas通知所有暂停的线程继续运行
21.   canvas.notifyAll();
22.  }
23. }
24. this.requestFocus();//Applet接受光标,以便其接受按键事件

25. }
26. …
27. }

  在jButton1的按钮点击事件处理方法里根据statusCode所标识的游戏状态分别进行处理:

  ·当statusCode=0时,游戏原处于结束或未开始的状态,表示用户执行开始游戏的命令。开始一个新游戏的命令,将统计数据归0,根据画布当前的宽度和栏数计算出每栏的宽度,实例化一个产生器线程,并切换按钮的图标为暂停图标,将停止按钮置为激活态。

  ·当statusCode=1时,游戏原处于运行态,表示用户执行暂停的命令。更改状态并更换按钮的图标。

  ·当statusCode=2时,游戏原处于暂停态,表示用户执行暂停后继续游戏的命令。更改状态并更换按钮图标,通过canvas对象通知所有暂停的线程。

  其次,给停止按钮jButton2生成以下的事件响应代码:

  代码清单 9 停止游戏的事件处理代码

1. …
2. public class TypeTrainApplet extends JApplet {
3.  …
4.  public void jButton2_actionPerformed(ActionEvent e) {
5.   statusCode = 0;
6.   synchronized (canvas) {
7.    canvas.notifyAll();
8.   }
9.   jButton2.setEnabled(false);
10.   jButton1.setIcon(startIcon);

11.  }
12.  …
13. }

  首先更改游戏的状态,在第6~7行向所有处于等待状态的线程发出一个通知,防止线程"睡死"的情况。线程在循环体的判断语句中判断出statusCode为0后将纷纷退出,所有线程结束。而后,将按钮置为非激活状并将开始/暂停按钮切换为开始的图标。

  3、保存游戏统计数据

  为了演示通过数字签名技术突破Applet安全限制的方法,我们特地设计了一个功能:将游戏的统计数字写入到客户端机器的D:\result.txt文件中。在UI设计界面中双击jButton3的按钮,为"保存"按钮添加如下的事件处理方法:

  代码清单 10 保存按钮事件处理方法

1. …
2. import java.io.*;
3. public class TypeTrainApplet extends JApplet {
4.  …
5.  public void jButton3_actionPerformed(ActionEvent e) {
6.   FileWriter fw = null;
7.   try {
8.    File file = new File("d:\\result.txt");
9.    fw = new FileWriter(file);
10.    fw.write("总数:" + totalCount + "\n");
11.    fw.write("正确数:" + rightCount + "\n");
12.    fw.write("失败数:" + errorCount);
13.    fw.flush();
14.    JOptionPane.showMessageDialog(this, "成绩成功保存到d:\result.txt中",
15.              "信息",JOptionPane.OK_OPTION);
16.    } catch (IOException ex) {
17.     ex.printStackTrace();
18.    } finally {
19.     try {
20.      if (fw != null) {
21.       fw.close();
22.      }
23.     } catch (IOException ex1) {
24.      ex1.printStackTrace();
25.     }
26.    }

27.   }
28.   …
29.  }

  至此,我们就完成了整个游戏的开发过程,Rebuild事件工程,在<工程根目录>/classes文件夹下双击打开Applet向导为我们所生成的TypeTrainApplet.html网页,假如你机器已经安装了JRE,我们的指法练习游戏将在网页中打开,点击开始按钮玩伙自己亲手制作的游戏,如下图所示:


图 13 在网页中运行指法练习Applet游戏

  点击停止按钮停止游戏,试着点击"保存"按钮,将统计数据保存到D:\result.txt中,你将会在Java控制台中看到一个安全异常信息,如下图所示:


图 14 Applet的功能被安全管理器限制

  因为一般的Applet运行在称为"沙盒"的安全模块下,Applet虽然在客户端机器上运行,但至多只是一个"外来客",客户机没有将其当作"自家人"来对待。所以Applet不能执行访问本地文件系统、执行本地程序,保存统计数据到文件也就发生异常了。在本章后面,我们将详细介绍如何通过数字签名的技术来绕过Applet的安全限制,让客户机将这个"外来客"宾至如归。

  4、关注Applet生命周期

  Applet在浏览器中运行时,第一次加载Applet,将调用init()方法,接着调用start(),当窗口关闭或页面替换时先调用stop()然后再调用destroy()。

  因为我们的游戏是多线程的程序,当关闭浏览器时,如果Applet的字母下落线程还在运行可能会引发异常。在JBuilder中右击TypeTrainApplet.html,在弹出的菜单中选择Run using default,JBuilder使用AppletViewer运行TypeTrainApplet。启动游戏后直接关闭窗口,在信息窗格中将报告以下的异常信息:

  java.lang.NullPointerException
  at game.TypeTrainApplet$DropCharThread.draw(TypeTrainApplet.java:290)
  at game.TypeTrainApplet$DropCharThread.run(TypeTrainApplet.java:258)

  这是由于关闭AppletViewer后,TypeTrainApplet画布的Graphics对象先被销毁,而字母下落线程依然调用访问这个对象,所以抛出空指针异常。

  我们可以通过Applet的生命周期解决这个问题:Applet在被关闭前会调用stop()和destroy()方法。我们只要利用stop()方法就可以了,在stop()方法中置一个标识,线程通过判断这个标识就可以知道当前窗口是否关闭,当发现关闭时就不再运行。

1. public class TypeTrainApplet extends JApplet {
2.  …
3.  boolean isClose = false;//用于标识Applet窗口有没有关闭
4.  …
5.  public void start() {
6.   isClose = false;
7.  }
8.
9.  public void stop() {
10.   statusCode = 0;//停止游戏
11.   isClose = true;//窗口关闭

12.  }
13.  …
14.  private class DropCharThread extends Thread {
15.   if(isClose) return ;//发现窗口关闭马上返回
16.   draw(ACTION_DRAW_FONT);
17.   try {
18.    while (c != pressKeyChar && y < canvas.getHeight() &&
19.           statusCode != 0) {
20.     synchronized (canvas) {
21.      while (statusCode == 2) {
22.       canvas.wait();
23.      }
24.     }
25.     draw(ACTION_CLEAR_FONT);
26.     y += stepLen;
27.     draw(ACTION_DRAW_FONT);
28.     Thread.sleep(stepInterval);
29.    }
30.    } catch (InterruptedException ex) {
31.   }
32.   if (!isClose) {//窗口没有关闭才后续处理
33.    draw(ACTION_CLEAR_FONT);
34.    if (statusCode != 0) { //游戏没有停止
35.     totalCount++; //统计总数
36.     if (y < canvas.getHeight()) {
37.      hitSound.play();
38.      rightCount++; //击中
39.     } else {
40.      errorCount++; //打不中
41.     }
42.     drawResult();
43.    }
44.   }
45.  }
46. }

  Applet启动时调用start()方法,这方法里将窗口关闭标识置为false,如第6行所示,而当窗口关闭时stop()方法被调用,停止游戏并置窗口关闭标识,如第10~11行所示。字母下落线程的程序也要作相应的调整,在进入线程和结束线程都判断是否关闭了窗口。


上一页  1 2 3 4 5 6 7  下一页

发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
天极社区邀请您:写博客日记  上传相片   论坛聊天  订阅电子杂志  推荐网摘   免费图铃工具
笔名:   请您注意:

 遵守国家有关法律、法规,尊重网上道德,承担一切因您的行为而直接或间接引起的法律责任。

 天极网拥有管理笔名和留言的一切权利。
评论:
 
,Java相关内容,Java焦点新闻
  • 关于Java栈与堆的思考
  • 大道至简 Java 23种模式一点就通
  • JavaBeans程序开发从入门到精通
  • 使用SWT开发基于Java的图形用户界面
  • Java加密和数字签名编程快速入门
  • FVD刺激高清碟机加速商业化 抢占商机最重要
  • 3家搜索引擎集体诉讼8848 吕春维未敢出席
  • 杨元庆:没有准备不会获批的备用方案
  • 军队信息化诞生新领域 电子军务呼之欲出
  • 世界经济论坛公布信息化程度全球最新排名
  • 2004政务绩效评估:政府门户尚处于发展阶段
  • 甲骨文出资5.15亿美元 意图收购RetekInc
  • 技术并购:帮你突破传统增长的“天花板”
  • ,JavaAdvertisement