跟着王洋老师学编程 - 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) 编辑 收藏 举报