况下都应被调用:
·击中一个字母。
·一个字母下落到底端。
而resetGame()方法在点击开始按钮后调用,将3个统计变量归零,以便重新开始统计。
主体程序
1、字母下落线程
游戏界面中每一个下落的字母对应一个字母下落线程DropCharThread的实例,这个线程负责将一个随机的字母在指定的画布栏中从上至下落下。在TypeTrainApplet内部定义这个线程类,之所以要将其作为成员内部类来定义,是因为这样可以减少类和类之间的通信,降低调用接口的复杂度。DropCharThread需要访问到TypeTrainApplet的众多成员,作为内部类就可以直接访问TypeTrainApplet类的成员变量了。其代码如下所示:
代码清单 4 DropCharThread字母下落线程
1. …
2. public class TypeTrainApplet extends JApplet {
3. …
4. private class DropCharThread extends Thread {
5. char c; //对应的字符
6. int colIndex; //在哪列下落
7. int x, y; //行列的坐标
8. private static final int ACTION_DRAW_FONT = 1; //画字符
9. private static final int ACTION_CLEAR_FONT = 2; //清字符
10. public DropCharThread(char c, int colIndex) {
11. this.c = c;
12. this.colIndex = colIndex;
13. this.x = (colIndex - 1) * colWidth + colWidth / 2; //所在的横坐标
14. }
15. //线程方法
16. public void run() {
17. draw(ACTION_DRAW_FONT);
18. try {
19. while (c != pressKeyChar && y < canvas.getHeight() && 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.
33. pressKeyChar = '' '';
34. draw(ACTION_CLEAR_FONT);
35. if (statusCode != 0) {//游戏没有停止
36. totalCount++; //统计总数
37. if (y < canvas.getHeight()) {
38. rightCount++; //击中
39. } else {
40. errorCount++; //打不中
41. }
42. drawResult();
43. }
44. }
45.
46. /**
47. * 画字母
48. * @param actionType 1:画字母 2: 清除字母
49. */
50. private void draw(int actionType) {
51. synchronized (canvas) { //必须对资源canvas进行同步,否则会产生线程不安全
52. Graphics g = canvas.getGraphics();
53. if (actionType == ACTION_CLEAR_FONT) {
54. g.setXORMode(canvas.getBackground()); //清除
55. }
56. g.setFont(new Font("Times New Roman", Font.PLAIN, 12));
57. g.drawString("" + c, x, y);
58. }
59. }
60. }
61. …
62. }
JBuilder 2005开发Applet游戏全接触(8)
时间:2010-04-27 天极
由于这个类比较关键,逻辑也比较复杂,为了方便说明,我们将其流程通过一个流程图来描述,如下图所示:
图 11 字母下落线程流程图
1) 首先在栏序号为colIndex的栏的第一个位置画出保存在变量c中的字母(第17行)。
2) 当这个字母未被击中,未到达画布底部且用户未结束游戏进行循环,这步判断对应程序的19行。如果这个判断条件通过进入第3步,即进入循环体,否则转到第5步。
3) 如果被暂停,这个线程进入等待态,直接被通知后才继续运行。需要指明一点的是,所有字母下落线程都用画布对 |