shannonredeemed

跟着王洋老师学编程 - 1.8 打字母游戏

一、案例简述

在一个300*400的窗体上,有10个随机产生的字母向下落,在键盘上敲字母,如果对了就消掉,初始成绩为1000分,每敲对一个字母加10分,如果字母落到屏幕下方,或者敲错扣100分。

二、我的思路

- 创建一个窗体

- 创建一个字母画布类 —— 继承画布类Panel、编写构造方法以初始化数据,实现多线程接口、重写run方法,实现键盘监听接口、重写其中的抽象方法,

- 将画布添加至窗体,启动线程,将窗体设置为可见

代码一

 1 import java.awt.*;
 2 public class LetterGame{
 3     public static void main(String args[]){
 4         Frame w = new Frame();
 5         w.setSize(400,300);
 6 
 7         LetterPanel lp = new LetterPanel();
 8         w.add(lp);
 9 
10         w.addKeyListener(lp);
11         lp.addKeyListener(lp);
12         
13         Thread t = new Thread(lp);
14         t.start();
15 
16         w.setVisible(true);        
17     }
18 }
19 
20 class LetterPanel extends Panel implements Runnable,KeyListener{
21     String ls="a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
22     // 初始化字母数组
23     String[] cs;
24     // 初始化积分
25     int score = 1000;
26     int[] xs=[],ys=[];
27     public LetterPanel(){
28         for (int i=0; i<10;i++){
29             cs[i]=ls.split("")[(int)(Math.random()*52)];
30             xs[i]=(int)(Math.random()*400);
31             ys[i]=(int)(Math.random()*300);
32         }
33         System.out.println(cs);    // 打印cs数组试试
34     }
35 
36     public void paint(Graphics g){
37         for(int j=0;j<10;j++){
38             g.drawString(cs[j],xs[j],ys[j]);
39         }
40     }
41     // 所有字母持续下落,直到积分清0
42     public void run(){
43         while(score>0){
44             for (int k=0; k<10;k++){
45                 xs[k]-=(int)(Math.random()*40);
46                 ys[k]-=(int)(Math.random()*30);
47                 if(xs[k]>300 || ys[k]>400){
48                     score-=50;
49                 }
50             }
51             try{
52                 Thread.sleep(300);
53             }catch(Exception e){
54                 System.out.println(e);
55             }    
56             repaint();        
57         }
58     }
59 
60     @Override
61     public void keyPressed(KeyEvent ke){
62         int kc = ke.getKeyChar();
63         System.out.println(kc);
64         for(int m=0;m<10;m++){
65             char c = String.copyValueOf(cs[m]);
66             char c2 = cs.charAt(m);
67             System.out.println(c + " " + c2);
68             if(kc==c2 || kc == c){
69                 score +=10;
70                 ys[m]=300;
71                 // 补充掉落的字母
72                 cs[k]=ls.split("")[(int)(Math.random()*52)];    
73                 xs[k]=(int)(Math.random()*400);
74                 ys[k]=(int)(Math.random()*300);
75             }
76         }    
77     }
78     @Override
79     public void keyReleased(KeyEvent ke){
80     
81     }
82     @Override
83     public void keyTyped(KeyEvent ke){
84     
85     }                                
86 }

编译报错:

 看起来是定义字母的X\Y数组时不规范,修改代码重新执行。

代码二

 1 class LetterPanel extends Panel implements Runnable,KeyListener{
 2     String ls="a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
 3     // 初始化字母数组
 4     String[] cs;
 5     // 初始化积分
 6     int score = 1000;
 7     int[] xs,ys;    // 去掉了=[]
 8     public LetterPanel(){
 9         for (int i=0; i<10;i++){
10             cs[i]=ls.split("")[(int)(Math.random()*52)];
11             xs[i]=(int)(Math.random()*400);
12             ys[i]=(int)(Math.random()*300);
13         }
14         System.out.println(cs);    // 打印cs数组试试
15     }
16 
17     public void paint(Graphics g){
18         for(int j=0;j<10;j++){
19             g.drawString(cs[j],xs[j],ys[j]);
20         }
21     }

编译仍然报错:

 看起来,将xs,ys定义在一行,好像不行,修改试试。

代码三

 1 class LetterPanel extends Panel implements Runnable,KeyListener{
 2     String ls="a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
 3     // 初始化字母数组
 4     String[] cs;
 5     // 初始化积分
 6     int score = 1000;
 7     int[] xs;
 8     int[] ys;    // 将xs,ys拆分为两行
 9     public LetterPanel(){
10         for (int i=0; i<10;i++){
11             cs[i]=ls.split("")[(int)(Math.random()*52)];
12             xs[i]=(int)(Math.random()*400);
13             ys[i]=(int)(Math.random()*300);
14         }
15         System.out.println(cs);    // 打印cs数组试试
16     }

编译报错,上一个问题解决了,因此暴露出更多问题

 

经过排查,发现三类问题:

1. 一个类可以实现多个接口,因此错误应该不在标点符号之类,再检查,发现,没有导入java.awt.event.*,需要补上;

2. String类型 和 char 类型 的转换仍然有问题,百度时,忽然想到string类型能不能之间转int,结果竟然有这种做法! Integer.parseInt("123")—— 需要专题研究

3. 再检查,发现总是找不到k,发现补充新的字母时,循环的变量未修改

代码四

 1 import java.awt.*;
 2 import java.awt.event.*;
 3 public class LetterGame{
 4     public static void main(String args[]){
 5         Frame w = new Frame();
 6         w.setSize(400,300);
 7 
 8         LetterPanel lp = new LetterPanel();
 9         w.add(lp);
10 
11         w.addKeyListener(lp);
12         lp.addKeyListener(lp);
13         
14         Thread t = new Thread(lp);
15         t.start();
16 
17         w.setVisible(true);        
18     }
19 }
20 
21 class LetterPanel extends Panel implements Runnable,KeyListener{
22     String ls="a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
23     // 初始化字母数组
24     String[] cs;
25     // 初始化积分
26     int score = 1000;
27     int[] xs;
28     int[] ys;    // 将xs,ys拆分为两行
29     public LetterPanel(){
30         for (int i=0; i<10;i++){
31             cs[i]=ls.split(" ")[(int)(Math.random()*52)];
32             xs[i]=(int)(Math.random()*400);
33             ys[i]=(int)(Math.random()*300);
34         }
35         System.out.println(cs);    // 打印cs数组试试
36     }
37 
38     public void paint(Graphics g){
39         this.setBackground(Color.black);
40         for(int j=0;j<10;j++){
41             g.setColor(Color.white); // 背景-#fef3d7  字母#fdcb23 #7bc9d1  #f1827a  #a8c83b  #ef8277
42             g.drawString(cs[j],xs[j],ys[j]);
43         }
44     }
45     // 所有字母持续下落,直到积分清0
46     public void run(){
47         while(score>0){
48             for (int k=0; k<10;k++){
49                 xs[k]-=(int)(Math.random()*40);
50                 ys[k]-=(int)(Math.random()*30);
51                 if(xs[k]>300 || ys[k]>400){
52                     score-=50;
53                 }
54             }
55             try{
56                 Thread.sleep(300);
57             }catch(Exception e){
58                 System.out.println(e);
59             }    
60             repaint();        
61         }
62     }
63 
64     @Override
65     public void keyPressed(KeyEvent ke){
66         int kc = ke.getKeyCode();
67         System.out.println("kc: "+kc);
68         for(int m=0;m<10;m++){
69             int c = Integer.parseInt(cs[m]);
70             System.out.println("c: "+c);
71             if(kc == c){
72                 score +=10;
73                 ys[m]=300;
74                 // 补充掉落的字母
75                 cs[m]=ls.split(" ")[(int)(Math.random()*52)];    
76                 xs[m]=(int)(Math.random()*400);
77                 ys[m]=(int)(Math.random()*300);
78             }
79         }    
80     }
81     @Override
82     public void keyReleased(KeyEvent ke){
83     
84     }
85     @Override
86     public void keyTyped(KeyEvent ke){
87     
88     }                                
89 }

编译通过!但执行报错了——

 仔细看了一下,错误是在主函数的第8行,LetterPanel类的构造方法里第31行 报的,嗯。。对照了一下书中的字母和数字数组,长度没定义……修改如下。

代码五

 1 class LetterPanel extends Panel implements Runnable,KeyListener{
 2     String ls="a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
 3     // 初始化字母数组
 4     string[] cs = new string[10];
 5     // 初始化积分
 6     int score = 1000;
 7     int[] xs = new int[10];
 8     int[] ys = new int[10];    // 将xs,ys拆分为两行 + 加上长度定义
 9     public LetterPanel(){
10         for (int i=0; i<10;i++){
11             cs[i]=ls.split(" ")[(int)(Math.random()*51)];
12             xs[i]=(int)(Math.random()*400);
13             ys[i]=(int)(Math.random()*300);
14         }
15         System.out.println(cs);    // 打印cs数组试试
16     }

编译报错:

 思考了下,string 与 String不同,所以改一版,然后暴露出更多问题,一口气改了好几版,直到最后……可以用了!!!

代码六

 1 import java.awt.*;
 2 import java.awt.event.*;
 3 public class LetterGame{
 4     public static void main(String args[]){
 5         Frame w = new Frame();
 6         w.setSize(400,300);
 7 
 8         LetterPanel lp = new LetterPanel();
 9         w.add(lp);
10 
11         w.addKeyListener(lp);
12         lp.addKeyListener(lp);
13         
14         Thread t = new Thread(lp);
15         t.start();
16 
17         w.setVisible(true);        
18     }
19 }
20 
21 class LetterPanel extends Panel implements Runnable,KeyListener{
22     // String ls="a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
23     String ls="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
24     char[] lcs=ls.toCharArray();
25     // 初始化字母数组
26     // String[] cs = new String[10];
27     // char[] cs = new Character[10];
28     Character[] cs = new Character[10];
29     // 初始化积分
30     int score = 1000;
31     int[] xs = new int[10];
32     int[] ys = new int[10];    // 将xs,ys拆分为两行 + 加上长度定义
33     public LetterPanel(){
34         for (int i=0; i<10;i++){
35             // cs[i]=ls.split(" ")[(int)(Math.random()*51)];
36             cs[i]=lcs[(int)(Math.random()*51)];
37             xs[i]=(int)(Math.random()*400);
38             ys[i]=(int)(Math.random()*300);
39             System.out.println(cs[i]+" " + ys[i]);    // 打印cs数组试试
40         }
41     }
42 
43     public void paint(Graphics g){
44         this.setBackground(Color.black);
45         for(int j=0;j<10;j++){
46             g.setColor(Color.white); // 背景-#fef3d7  字母#fdcb23 #7bc9d1  #f1827a  #a8c83b  #ef8277
47             g.drawString(Character.toString(cs[j]),xs[j],ys[j]);
48         }
49     }
50     // 所有字母持续下落,直到积分清0
51     public void run(){
52         while(score>0){
53             for (int k=0; k<10;k++){
54                 //xs[k]-=(int)(Math.random()*40); // change
55                 ys[k]+=(int)(Math.random()*30);    // change
56                 if(ys[k]>300){
57                     score-=50;
58                 }
59                 System.out.println(k +" "+score+cs[k]+" " + ys[k]);    // 打印cs数组试试
60             }
61             try{
62                 Thread.sleep(1000);
63             }catch(Exception e){
64                 System.out.println(e);
65             }    
66             repaint();        
67         }
68     }
69 
70     @Override
71     public void keyPressed(KeyEvent ke){
72         int kc = ke.getKeyCode();
73         System.out.println("kc: "+kc);
74         for(int m=0;m<10;m++){
75             //int c = Integer.parseInt(cs[m]);
76             int c = (int)(cs[m]);
77             System.out.println("c: "+c);
78             if(kc == c){
79                 score +=10;
80                 ys[m]=300;
81                 // 补充掉落的字母
82                 // cs[m]=ls.split(" ")[(int)(Math.random()*52)];
83                 // cs[i]=lcs[(int)(Math.random()*51)];    
84                 cs[m]=lcs[(int)(Math.random()*51)];
85                 xs[m]=(int)(Math.random()*400);
86                 ys[m]=0;
87             }
88         }    
89     }
90     @Override
91     public void keyReleased(KeyEvent ke){
92     
93     }
94     @Override
95     public void keyTyped(KeyEvent ke){
96     
97     }                                
98 }

 发现缺少敲错也要扣分、掉落后也要补字母的逻辑,并作了其他一些微调(见注释)

 代码七

  1 import java.awt.*;
  2 import java.awt.event.*;
  3 public class LetterGame{
  4     public static void main(String args[]){
  5         Frame w = new Frame();
  6         w.setSize(400,300);
  7 
  8         LetterPanel lp = new LetterPanel();
  9         w.add(lp);
 10 
 11         w.addKeyListener(lp);
 12         lp.addKeyListener(lp);
 13         
 14         Thread t = new Thread(lp);
 15         t.start();
 16 
 17         w.setVisible(true);        
 18     }
 19 }
 20 
 21 class LetterPanel extends Panel implements Runnable,KeyListener{
 22     // String ls="a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
 23     String ls="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 24     char[] lcs=ls.toCharArray();
 25     // 初始化字母数组
 26     // String[] cs = new String[10];
 27     // char[] cs = new Character[10];
 28     Character[] cs = new Character[10];
 29     // 初始化积分
 30     int score = 5000;    //  增加初始分数
 31     int[] xs = new int[10];
 32     int[] ys = new int[10];    // 将xs,ys拆分为两行 + 加上长度定义
 33     public LetterPanel(){
 34         for (int i=0; i<10;i++){
 35             // cs[i]=ls.split(" ")[(int)(Math.random()*51)];
 36             cs[i]=lcs[(int)(Math.random()*51)];
 37             xs[i]=(int)(Math.random()*400);
 38             ys[i]=(int)(Math.random()*300);
 39             System.out.println(cs[i]+" " + ys[i]);    // 打印cs数组试试
 40         }
 41     }
 42 
 43     public void paint(Graphics g){
 44         this.setBackground(Color.green);
 45         for(int j=0;j<10;j++){
 46             //g.setColor(Color.white); // 背景-#fef3d7  字母#fdcb23 #7bc9d1  #f1827a  #a8c83b  #ef8277
 47             g.setColor(Color.yellow);
 48             g.setColor(Color.orange);
 49             g.setColor(Color.red);
 50             g.drawString(Character.toString(cs[j]),xs[j],ys[j]);
 51         }
 52     }
 53     // 所有字母持续下落,直到积分清0
 54     public void run(){
 55         while(score>0){
 56             for (int k=0; k<10;k++){
 57                 //xs[k]-=(int)(Math.random()*40); // change
 58                 ys[k]+=(int)(Math.random()*30);    // change
 59                 if(ys[k]>300){
 60                     score-=50;
 61                     // 也要补充掉落的字母    
 62                     cs[k]=lcs[(int)(Math.random()*51)];
 63                     xs[k]=(int)(Math.random()*400);
 64                     ys[k]=0;
 65                 }
 66                 System.out.println(k +" "+score+cs[k]+" " + ys[k]);    // 打印cs数组试试
 67             }
 68             try{
 69                 Thread.sleep(1000);
 70             }catch(Exception e){
 71                 System.out.println(e);
 72             }    
 73             repaint();        
 74         }
 75     }
 76 
 77     @Override
 78     public void keyPressed(KeyEvent ke){
 79         int kc = ke.getKeyCode();
 80         boolean boo=true;
 81         System.out.println("kc: "+kc);
 82         for(int m=0;m<10;m++){
 83             //int c = Integer.parseInt(cs[m]);
 84             int c = (int)(cs[m]);
 85             System.out.println("c: "+c);
 86             if(kc == c){        // 还差一块逻辑,如果没有匹配的,也要扣分
 87                 score +=10;
 88                 ys[m]=300;
 89                 // 补充匹配掉的字母
 90                 // cs[m]=ls.split(" ")[(int)(Math.random()*52)];
 91                 // cs[i]=lcs[(int)(Math.random()*51)];    
 92                 cs[m]=lcs[(int)(Math.random()*51)];
 93                 xs[m]=(int)(Math.random()*400);
 94                 ys[m]=0;
 95                 boo=false;
 96             }
 97         }
 98         if(boo){    // 没有匹配也要扣分
 99             score-=50;    
100         }
101         
102     }
103     @Override
104     public void keyReleased(KeyEvent ke){
105     
106     }
107     @Override
108     public void keyTyped(KeyEvent ke){
109     
110     }                                
111 }

编译通过,但反复游戏,发现,程序只能识别大写字母,小写字母无法识别,重新打印输入和匹配情况,发现确实有问题;再检查API中KeyEvent的说明,没有很明确,但决定把ke.getCode()改成(int)ke.getKeyChar(),破案

 

代码八

  1 import java.awt.*;
  2 import java.awt.event.*;
  3 public class LetterGame{
  4     public static void main(String args[]){
  5         Frame w = new Frame();
  6         w.setSize(400,300);
  7 
  8         LetterPanel lp = new LetterPanel();
  9         w.add(lp);
 10 
 11         w.addKeyListener(lp);
 12         lp.addKeyListener(lp);
 13         
 14         Thread t = new Thread(lp);
 15         t.start();
 16 
 17         w.setVisible(true);        
 18     }
 19 }
 20 
 21 class LetterPanel extends Panel implements Runnable,KeyListener{
 22     // String ls="a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
 23     String ls="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 24     char[] lcs=ls.toCharArray();
 25     // 初始化字母数组
 26     // String[] cs = new String[10];
 27     // char[] cs = new Character[10];
 28     Character[] cs = new Character[10];
 29     // 初始化积分
 30     int score = 5000;    //  增加初始分数
 31     int[] xs = new int[10];
 32     int[] ys = new int[10];    // 将xs,ys拆分为两行 + 加上长度定义
 33     public LetterPanel(){
 34         for (int i=0; i<10;i++){
 35             // cs[i]=ls.split(" ")[(int)(Math.random()*51)];
 36             cs[i]=lcs[(int)(Math.random()*51)];
 37             xs[i]=(int)(Math.random()*400);
 38             ys[i]=(int)(Math.random()*300);
 39             //System.out.println(cs[i]+" " + ys[i]);    // 打印cs数组试试
 40         }
 41     }
 42 
 43     public void paint(Graphics g){
 44         this.setBackground(Color.green);
 45         for(int j=0;j<10;j++){
 46             //g.setColor(Color.white); // 背景-#fef3d7  字母#fdcb23 #7bc9d1  #f1827a  #a8c83b  #ef8277
 47             g.setColor(Color.yellow);
 48             g.setColor(Color.orange);
 49             g.setColor(Color.red);
 50             g.drawString(Character.toString(cs[j]),xs[j],ys[j]);
 51         }
 52     }
 53     // 所有字母持续下落,直到积分清0
 54     public void run(){
 55         while(score>0){
 56             for (int k=0; k<10;k++){
 57                 //xs[k]-=(int)(Math.random()*40); // change
 58                 ys[k]+=(int)(Math.random()*30);    // change
 59                 if(ys[k]>300){
 60                     score-=50;
 61                     System.out.println("Missed! "+score);
 62                     // 也要补充掉落的字母    
 63                     cs[k]=lcs[(int)(Math.random()*51)];
 64                     xs[k]=(int)(Math.random()*400);
 65                     ys[k]=0;
 66                 }
 67                 //System.out.println(k +" "+score+cs[k]+" " + ys[k]);    // 打印cs数组试试
 68             }
 69             try{
 70                 Thread.sleep(1000);
 71             }catch(Exception e){
 72                 System.out.println(e);
 73             }    
 74             repaint();        
 75         }
 76     }
 77 
 78     @Override
 79     public void keyPressed(KeyEvent ke){
 80 
 81         
 82     }
 83     @Override
 84     public void keyReleased(KeyEvent ke){
 85         int kc = ke.getKeyCode();     // 这个不好用,A和a返回的都是65
 86         // char kcc = ke.getKeyChar();
 87         int kcc = (int)ke.getKeyChar(); // 这个可以
 88         boolean boo=true;
 89         if(kcc>=65 && kcc<=123){    // 满足[a-zA-Z]的输入条件,才进入循环判断
 90             System.out.println(kcc+" "+kc);
 91             for(int m=0;m<10;m++){
 92                 //int c = Integer.parseInt(cs[m]);
 93                 int c = (int)(cs[m]);
 94                 System.out.println(cs[m]+": "+c);
 95                 if(kcc == c){        // 还差一块逻辑,如果没有匹配的,也要扣分
 96                     score +=10;
 97                     System.out.println("Matcher! "+score);
 98                     ys[m]=300;
 99                     // 补充匹配掉的字母
100                     // cs[m]=ls.split(" ")[(int)(Math.random()*52)];
101                     // cs[i]=lcs[(int)(Math.random()*51)];    
102                     cs[m]=lcs[(int)(Math.random()*51)];
103                     xs[m]=(int)(Math.random()*400);
104                     ys[m]=0;
105                     boo=false;
106                 }
107             }
108             if(boo){    // 没有匹配也要扣分
109                 score-=50;
110                 System.out.println("Wrong Target! "+score);    
111             }    
112         }
113     }
114     @Override
115     public void keyTyped(KeyEvent ke){
116     
117     }                                
118 }

 三、老师的思路

第一步,做满天星星。

代码一

 1 import java.awt.*;
 2 
 3 public class LetterGameT{
 4     public static void main(String[] args){
 5         Frame w = new Frame();
 6         w.setSize(300,400);
 7         w.setLocation(new Point((1366-300)/2,(768-400)/2));
 8         
 9         LetterPanelT lpt = new LetterPanelT();
10         w.add(lpt);
11         
12         Thread t = new Thread(lpt);
13         t.start();
14         
15         w.setVisible(true);        
16     }
17 }
18 
19 class LetterPanelT extends Panel implements Runnable{
20     int[] xs=new int[10];
21     int[] ys=new int[10];
22     
23     public LetterPanelT(){
24         for(int i=0;i<10;i++){
25             xs[i]=(int)(Math.random()*290+5);
26             ys[i]=(int)(Math.random()*300);
27         }
28     }
29     public void paint(Graphics g){
30         for(int j=0;j<10;j++){
31             g.drawString("*",xs[j],ys[j]);
32         }
33     }
34 
35     public void run(){
36         while(true){
37             // 星星下落
38             for(int k=0;k<10;k++){
39                 // xs[k]+=(int)(Math.random()*20);
40                 ys[k]+=(int)(Math.random()*15);                
41             }
42             try{
43                 Thread.sleep(300);
44             }catch(Exception e){
45                 
46             }
47             repaint();
48         }
49     }    
50 }

亮点

1. 窗体颜色没有另外设计;

2. 星星的坐标最大值没有取窗体边界值,防止星星一出来就在屏幕的最下方或最右方。

第二步,将星星改成10个不断下落的随机字母

代码二

 1 import java.awt.*;
 2 
 3 public class LetterGameT{
 4     public static void main(String[] args){
 5         Frame w = new Frame();
 6         w.setSize(300,400);
 7         w.setLocation(new Point((1366-300)/2,(768-400)/2));
 8         
 9         LetterPanelT lpt = new LetterPanelT();
10         w.add(lpt);
11         
12         Thread t = new Thread(lpt);
13         t.start();
14         
15         w.setVisible(true);        
16     }
17 }
18 
19 class LetterPanelT extends Panel implements Runnable{
20     char[] cs=new char[10];
21     int[] xs=new int[10];
22     int[] ys=new int[10];
23     
24     public LetterPanelT(){
25         for(int i=0;i<10;i++){
26             cs[i]=(char)(Math.random()*26+97);    // 只有a-z,没有A-Z
27             xs[i]=(int)(Math.random()*290+5);
28             ys[i]=(int)(Math.random()*300);
29         }
30     }
31     public void paint(Graphics g){
32         for(int j=0;j<10;j++){
33             // g.drawString("*",xs[j],ys[j]);
34             g.drawString(new Character(cs[j]).toString(),xs[j],ys[j]);
35         }
36     }
37 
38     public void run(){
39         while(true){
40             // 星星下落
41             for(int k=0;k<10;k++){
42                 // xs[k]+=(int)(Math.random()*20);
43                 ys[k]+=(int)(Math.random()*15);    
44                 if(ys[k]>400){            // 字母掉落后,重新补充A-Z
45                     cs[k]=(char)(Math.random()*26+65);
46                     xs[k]=(int)(Math.random()*290+5);
47                     ys[k]=0;
48                 }            
49             }
50             try{
51                 Thread.sleep(300);
52             }catch(Exception e){
53                 
54             }
55             repaint();
56         }
57     }    
58 }

 第四步,接收键盘输入并消除匹配的字母

代码三

修改报错问题:

1. 导入的包缺失,导致实现KeyListener接口报错

2. @override 关键字写错,应该是大小写问题Override

代码四

 1 import java.awt.*;
 2 import java.awt.event.*;
 3 
 4 public class LetterGameT{
 5     public static void main(String[] args){
 6         Frame w = new Frame();
 7         w.setSize(300,400);
 8         w.setLocation(new Point((1366-300)/2,(768-400)/2));
 9         
10         LetterPanelT lpt = new LetterPanelT();
11         w.add(lpt);
12         
13         Thread t = new Thread(lpt);
14         t.start();
15         
16         w.setVisible(true);        
17     }
18 }
19 
20 class LetterPanelT extends Panel implements Runnable, KeyListener{
21     char[] cs=new char[10];
22     int[] xs=new int[10];
23     int[] ys=new int[10];
24     
25     public LetterPanelT(){
26         for(int i=0;i<10;i++){
27             cs[i]=(char)(Math.random()*26+97);    // 只有a-z,没有A-Z
28             xs[i]=(int)(Math.random()*290+5);
29             ys[i]=(int)(Math.random()*300);
30         }
31     }
32     public void paint(Graphics g){
33         for(int j=0;j<10;j++){
34             // g.drawString("*",xs[j],ys[j]);
35             g.drawString(new Character(cs[j]).toString(),xs[j],ys[j]);
36         }
37     }
38 
39     public void run(){
40         while(true){
41             // 星星下落
42             for(int k=0;k<10;k++){
43                 // xs[k]+=(int)(Math.random()*20);
44                 ys[k]+=(int)(Math.random()*15);    
45                 if(ys[k]>400){            // 字母掉落后,重新补充A-Z
46                     cs[k]=(char)(Math.random()*26+65);
47                     xs[k]=(int)(Math.random()*290+5);
48                     ys[k]=0;
49                 }            
50             }
51             try{
52                 Thread.sleep(300);
53             }catch(Exception e){
54                 
55             }
56             repaint();
57         }
58     }
59 
60     @Override
61     public void keyTyped(KeyEvent ke){
62         // 第四步,接收键盘输入,并消除匹配的字母
63         char ch = ke.getKeyChar();
64         System.out.println(ch);
65         for(int m=0;m<10;m++){
66             System.out.println(cs[m]);
67             if(ch==cs[m]){
68                 // 匹配即消除,重新补充一个
69                 cs[m]=(char)(Math.random()*26+97);
70                 xs[m]=(int)(Math.random()*290+5);
71                 ys[m]=0;    
72             }
73         }
74     }
75 
76     @Override
77     public void keyPressed(KeyEvent ke){
78         
79     }    
80 
81     @Override
82     public void keyReleased(KeyEvent ke){
83         
84     }    
85     
86 }

编译并运行,发现键盘输入未生效。就是无论怎么输入,键盘监听事件都没触发——

百度查到如下标题文字,第一种原因就把问题解决了——没有注册组件的监听事件

https://blog.csdn.net/imonkeyi/article/details/86177348

解决后,进行下一步。

 第五步,接收键盘输入并消除匹配的字母

 

  1 import java.awt.*;
  2 import java.awt.event.KeyEvent;
  3 import java.awt.event.KeyListener;
  4 
  5 public class LetterGameT{
  6     public static void main(String[] args){
  7         Frame w = new Frame();
  8         w.setSize(300,400);
  9         w.setLocation(new Point((1366-300)/2,(768-400)/2));
 10         
 11         LetterPanelT lpt = new LetterPanelT();
 12         w.add(lpt);
 13         
 14         Thread t = new Thread(lpt);
 15         t.start();
 16 
 17         w.addKeyListener(lpt);
 18         lpt.addKeyListener(lpt);
 19         
 20         w.setVisible(true);        
 21     }
 22 }
 23 
 24 class LetterPanelT extends Panel implements Runnable,KeyListener{
 25     // 初始化字母数组、字母坐标和总积分
 26     char[] cs=new char[10];
 27     int[] xs=new int[10];
 28     int[] ys=new int[10];
 29     int score = 1000;
 30     
 31     public LetterPanelT(){
 32         for(int i=0;i<10;i++){
 33             cs[i]=(char)(Math.random()*26+97);    // 只有a-z,没有A-Z
 34             xs[i]=(int)(Math.random()*290+5);
 35             ys[i]=(int)(Math.random()*300);
 36         }
 37     }
 38     public void paint(Graphics g){
 39         for(int j=0;j<10;j++){
 40             // g.drawString("*",xs[j],ys[j]);
 41             g.drawString(new Character(cs[j]).toString(),xs[j],ys[j]);
 42         }
 43     }
 44 
 45     public void run(){
 46         while(score>=0){    // 总积分大于等于0,游戏才继续
 47             // 星星下落
 48             for(int k=0;k<10;k++){
 49                 // xs[k]+=(int)(Math.random()*20);
 50                 ys[k]+=(int)(Math.random()*15);    
 51                 if(ys[k]>400){            // 字母掉落后,重新补充A-Z
 52                     cs[k]=(char)(Math.random()*26+65);
 53                     xs[k]=(int)(Math.random()*290+5);
 54                     ys[k]=0;
 55                     score-=50;
 56                     System.out.println("score:"+score);
 57                 }            
 58             }
 59             try{
 60                 Thread.sleep(300);
 61             }catch(Exception e){
 62                 
 63             }
 64             repaint();
 65         }
 66     }
 67 
 68     @Override
 69     public void keyTyped(KeyEvent ke){
 70 
 71     }
 72 
 73     @Override
 74     public void keyPressed(KeyEvent ke){
 75         
 76     }    
 77 
 78     @Override
 79     public void keyReleased(KeyEvent ke){
 80         // 第四步,接收键盘输入,并消除匹配的字母
 81         boolean flag=false;
 82         char ch = ke.getKeyChar();
 83         System.out.println("score:"+score);
 84         for(int m=0;m<10;m++){
 85             // System.out.println(cs[m]);
 86             if(ch==cs[m]){
 87                 // 匹配即消除,重新补充一个
 88                 cs[m]=(char)(Math.random()*26+97);
 89                 xs[m]=(int)(Math.random()*290+5);
 90                 ys[m]=0;
 91                 score+=10;
 92                 flag=true;    
 93             }
 94         }
 95         if(!flag){// 说明键盘输入的字符与屏幕中的字符没有匹配上
 96             score-=50;    
 97         }
 98     }    
 99     
100 }

完美实现功能。

后记

其实,这个游戏,可以更进一步设计,设计成帮学生练习打字的游戏。

posted on 2024-02-02 22:44  Shannon_Zhang  阅读(9)  评论(0编辑  收藏  举报