跟着王洋老师学编程 - 1.4 飞行的小球(线程应用)
一、我的思路
- 画一个窗体,并设定大小
- 准备一个画布,并将画布添加至窗体
- 在画布上用paint方法实现小球的运动 —— 用一个for循环,小球x轴不变,先画一个球,然后改变画笔颜色与背景色相同,在原位置上再画一个小球;改变小球Y轴坐标,改变画笔颜色,在新的位置重新画小球,循环直到Y轴坐标达到窗体最大值结束。
代码版本1 - 直线下落:
1 import java.awt.Frame; 2 import java.awt.Panel; 3 import java.awt.Graphics; 4 import java.awt.Color; 5 public class DroppingBall{ 6 public static void main(String[] args){ 7 Frame w = new Frame(); 8 w.setSize(1366,768); 9 10 MyPanelB mpb = new MyPanelB(); 11 w.add(mpb); 12 w.show(); 13 } 14 } 15 16 class MyPanelB extends Panel{ 17 public void paint(Graphics g){ 18 int x=30,y=30; 19 g.drawOval(x,y,10,10); 20 for(;y<768;y++){ 21 g.setColor(Color.white); 22 g.drawOval(x,y,10,10); 23 y++; 24 g.setColor(Color.black); 25 g.drawOval(x,y,10,10); 26 } 27 } 28 }
编译及执行结果如下:
现象1 - 没有实现下落的动态效果,只显示一条直线。
思考1 - 是不是坐标变化的粒度太小,改为斜线呢。。?
代码版本2 - 斜线下落:
1 import java.awt.Frame; 2 import java.awt.Panel; 3 import java.awt.Graphics; 4 import java.awt.Color; 5 public class DroppingBall{ 6 public static void main(String[] args){ 7 Frame w = new Frame(); 8 w.setSize(1366,768); 9 10 MyPanelB mpb = new MyPanelB(); 11 w.add(mpb); 12 w.show(); 13 } 14 } 15 16 class MyPanelB extends Panel{ 17 public void paint(Graphics g){ 18 int x=5,y=5; 19 g.fillOval(x,y,10,10); 20 for(;x<1366;){ 21 for(;y<768;y++){ 22 g.setColor(Color.white); 23 g.fillOval(x,y,10,10); 24 x++; 25 y++; 26 g.setColor(Color.black); 27 g.fillOval(x,y,10,10); 28 } 29 } 30 } 31 }
编译及运行结果如下:
现象2 - 没有实现动态下落效果,只显示一条斜线。
思考2 - 小球没有按预想的在A位置出现、抹掉,在A+1位置重现、再抹掉……如果不用循环呢?
代码版本3 - 去掉循环。。:
1 import java.awt.Frame; 2 import java.awt.Panel; 3 import java.awt.Graphics; 4 import java.awt.Color; 5 public class DroppingBall{ 6 public static void main(String[] args){ 7 Frame w = new Frame(); 8 w.setSize(1366,768); 9 10 MyPanelB mpb = new MyPanelB(); 11 w.add(mpb); 12 w.show(); 13 } 14 } 15 16 class MyPanelB extends Panel{ 17 public void paint(Graphics g){ 18 int x=5,y=5; 19 g.fillOval(x,y,10,10); 20 g.setColor(Color.white); 21 g.fillOval(x,y,10,10); 22 x=30; 23 y=30; 24 g.setColor(Color.black); 25 g.fillOval(x,y,10,10); 26 27 g.setColor(Color.white); 28 g.fillOval(x,y,10,10); 29 x=100; 30 y=100; 31 g.setColor(Color.black); 32 g.fillOval(x,y,10,10); 33 } 34 }
编译及运行结果如下:
去掉循环之后,看不到线的轨迹了,说明旧位置的小球确实被“擦除”了,但看不到小球下落的效果;而加上循环,显示的却是小球的轨迹,看起来小球的旧位置并没有被“擦除”——
结论 - 不管循环是否存在,都没有实现小球动态下落的结果。。看起来如果能在原位置的小球“擦除”之后加入延时。。
二、老师的讲解
1、引入了线程,并线程与进程的区别
进程 - 一个独立运行的程序,比如一个正在运行的记事本、一个正在运行的浏览器;启动两次记事本,得到的也是两个线程。
线程 - 一个进程当中的单一顺序的控制流
https://m.runoob.com/java/java-multithreading.html
2、用线程实现小球下落效果的思路
代码版本1 - 线程固定用法
1 import java.awt.*; 2 public class DroppingBall{ 3 public static void main(String args[]){ 4 Frame w = new Frame(); 5 w.setSize(1366,768); 6 7 MyPanelB mpb = new MyPanelB(); 8 w.add(mpb); 9 10 // 使用线程对象 11 Thread t = new Thread(mpb); 12 t.start(); 13 14 // w.show(); 15 w.setVisible(true); 16 } 17 } 18 19 class MyPanelB extends Panel implements Runnable{ 20 int x=5,y=5; 21 public void paint(Graphics g){ 22 g.fillOval(x,y,10,10); 23 } 24 public void run(){ 25 while(true){ 26 y++; 27 if(y>768){ 28 y=5; 29 } 30 try{ 31 Thread.sleep(1000); 32 }catch(Exception e){ 33 System.out.println(e); 34 System.out.println(y); 35 repaint(); 36 } 37 } 38 } 39 }
编译并运行后,结果如下:
小球一直在初始位置不动。。各种打印后,发现try里面的代码执行了,但repaint()方法一直未执行,各种搜索博客也没解决。最后,去了一趟厕所,沉思……try...catch... catch是异常处理,发生异常,才抛出或处理异常,没有异常……啊!
结论:repaint()写错位置。。。。
代码版本2
1 import java.awt.*; 2 public class DroppingBall{ 3 public static void main(String args[]){ 4 Frame w = new Frame(); 5 w.setSize(1366,768); 6 7 MyPanelB mpb = new MyPanelB(); 8 w.add(mpb); 9 10 // 使用线程对象 11 Thread t = new Thread(mpb); 12 t.start(); 13 14 w.show(); 15 } 16 } 17 // 通过实现Runnable接口使用线程 18 class MyPanelB extends Panel implements Runnable{ 19 int x=5,y=5; 20 public void paint(Graphics g){ 21 g.fillOval(x,y,10,10); 22 } 23 public void run(){ 24 while(true){ 25 y++; 26 if(y>768){ 27 y=5; 28 } 29 try{ 30 Thread.sleep(1000); 31 }catch(Exception e){ 32 System.out.println(e); 33 } 34 repaint(); 35 } 36 } 37 }
编译及运行结果如下:
看到小球每秒下移一次~~~~~O(∩_∩)O~~~~~
三、最后优化
加快下移速度,并把过时的 show()方法,改为 setVisible(true)方法
1 import java.awt.*; 2 public class DroppingBall{ 3 public static void main(String args[]){ 4 Frame w = new Frame(); 5 w.setSize(1366,768); 6 7 MyPanelB mpb = new MyPanelB(); 8 w.add(mpb); 9 10 // 使用线程对象 11 Thread t = new Thread(mpb); 12 t.start(); 13 14 // w.show(); 15 w.setVisible(true); 16 } 17 } 18 // 通过实现Runnable接口使用线程 19 class MyPanelB extends Panel implements Runnable{ 20 int x=5,y=5; 21 public void paint(Graphics g){ 22 g.fillOval(x,y,10,10); 23 } 24 public void run(){ 25 while(true){ 26 y++; 27 if(y>768){ 28 y=5; 29 } 30 try{ 31 Thread.sleep(100); 32 }catch(Exception e){ 33 System.out.println(e); 34 } 35 repaint(); 36 } 37 } 38 }
小球实现了匀速下移!~
posted on 2023-12-13 12:05 Shannon_Zhang 阅读(22) 评论(0) 编辑 收藏 举报