Java多线程实现简单动画(小球运动)效果 您所在的位置:网站首页 多线程实现机制 Java多线程实现简单动画(小球运动)效果

Java多线程实现简单动画(小球运动)效果

2023-12-23 14:51| 来源: 网络整理| 查看: 265

目录

目录 1、多线程的两种实现方式 1.0、关于多线程理解1.1、Runnable1.2、Thread 2、实现动画效果的两种方式 2.0、实现过程理解2.1、画板(JPanel)线程2.2、物体(Object)线程

1、多线程的两种实现方式 1.0、关于多线程理解

首先,严格按照操作系统理论来说,多线程并没有实现真正的同时进行。而是CPU将工作时间分成很多很短的时间片(Time slicing),每个时刻只能执行一个线程。 时间分片 主要有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口。两种方式,除了创建线程实例的方式有差异外,启动线程都是调用start方法。

1.1、Runnable

Runnable接口中只有一个void run()方法,因此,实现Runnable接口需要实现run()方法。而启动多线程是通过将接口的实现类传入Thread进行实例化,然后调用start()方法。

public class HelloRunnable implements Runnable { public void run() { System.out.println("Hello from a thread!"); } public static void main(String args[]) { (new Thread(new HelloRunnable())).start(); } }

当然也可以通过匿名内部类实现临时的线程:

new Thread(new Runnable() { public void run() { System.out.println("Hello from a thread!"); } }).start();

Hint:由于类的继承是单一的,只能有一个父类,因此在类已经继承一个父类时,可以通过实现Runnable接口来实现线程。

1.2、Thread

Thread类本身也是通过实现Runnable接口实现的:

public class Thread extends Object implements Runnable

同样需要重写自己的run方法,启动线程也是调用start方法:

public class HelloThread extends Thread { public void run() { System.out.println("Hello from a thread!"); } public static void main(String args[]) { HelloThread p = new HelloThread(); p.start(); } public static void main(String args[]) { (new HelloThread()).start(); } } 2、实现动画效果的两种方式 2.0、实现过程理解

实现动画,就是让物体动起来,也就是说每次绘图时有规律的改变物体的位置即可。这里有两种实现方法,一种是将继承JPanel的类作为一个线程,一种是将物体类作为一个线程。两种方式实现效果差别不大,但前者更适用于多个物体一起改变位置的情况(同步),后者适用于物体各自改变位置的情况。

2.1、画板(JPanel)线程

创建一个类,继承JPanel类,实现Runnable接口。在其中重写paint方法,然后实现run()方法,run方法中调用repaint()方法,并使用循环和休眠来实现动画效果。

package test; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; /** * MyPanel.java. * @author Kaiyan Zhang */ public class MyPanel extends JPanel implements Runnable{ int x = 0,y = 400; @Override public void paint(Graphics g){ super.paint(g); g.drawOvel(x, y, 20, 20); } @Override public void run(){ while(true){ if(x>800) x = 0; else x = x + 10; this.repaint(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String [] args){ MyPanel p = new MyPanel(); /* panel thread, paint the monkey */ Thread panelThread = new Thread(p); JFrame frame = new JFrame(); frame.add(p); frame.setSize(800, 800); frame.setLocationRelativeTo(null); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); /* begin to paint */ panelThread.start(); } }

当然,需要绘制的物体也可以作为一个线程,每次改变位置,然后休眠,将物体传入MyPanel进行绘制。这里物体和MyPanel的休眠时间问题,后者的休眠时间更短一些,效果更好。 Hint: 重写paint方法时,一定要先调用父类的paint方法(super.paint(g)),这里后面才能使用repaint进行重写绘制。

2.2、物体(Object)线程

首先实现一个JPanel的子类MyPanel,在paint()方法中实现物体的绘制;然后创建一个运动物体类,继承Thread类,将MyPanel作为参数传入,实现run()方法,当然可以有一个位置成员变量,run方法中每次改变位置后,调用MyPanel.repaint()方法实现新的位置绘图,每次绘制后休眠一段时间。

package test; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; /** * MyPanel.java. * @author Kaiyan Zhang */ public class MyPanel extends JPanel { int x = 0, y = 400; Ball b; public MyPanel(Ball b) { this.b = b; b.start(); } @Override public void paint(Graphics g) { super.paint(g); g.drawOvel(b.x, b.y, 20, 20); } public static void main(String[] args) { Ball b = new Ball(); MyPanel p = new MyPanel(b); b.setPanel(p); /* panel thread, paint the monkey */ JFrame frame = new JFrame(); frame.add(p); frame.setSize(800, 800); frame.setLocationRelativeTo(null); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } class Ball extends Thread { int x = 0; int y = 400; MyPanel p; public void setPanel(MyPanel p) { this.p = p; } @Override public void run() { while (true) { if (x > 800) { x = 0; } else { x = x + 10; } p.repaint(); try { sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }

这里给出一个之前写的泡泡龙的代码,每次只有一个球进行运动,即使用该方法实现的 Bubble Shooter-使用线程实现泡泡龙



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有