Java applet重新绘制一个移动的圆圈

我刚从Pygame搬过来,所以applet中的Java 2D对我来说有点新鲜,特别是在重新绘制屏幕时。 在pygame中你可以简单地做display.fill([1,1,1])但是如何在Java中的applet中做到这一点? 我理解使用repaint()但是没有清除屏幕 – 任何移动的物体都没有从屏幕上“移除”,所以你得到一长串画圆。

这是我一直在测试的代码:

 package circles; import java.applet.Applet; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Random; public class circles extends Applet implements Runnable { private static final long serialVersionUID = -6945236773451552299L; static Random r = new Random(); String msg = "Click to play!"; static int w = 800, h = 800; int[] txtPos = { (w/2)-50,(h/2)-50 }; int[] radiusRange = { 5,25 }; int[] circles; static int[] posRange; int x = 0, y = 0; int radius = 0; int cursorRadius = 10; boolean game = false; public static int[] pos() { int side = r.nextInt(5-1)+1; switch(side) { case 1: posRange = new int[]{ 1,r.nextInt(w),r.nextInt((h+40)-h)+h,r.nextInt(270-90)+90 }; break; case 2: posRange = new int[]{ 2,r.nextInt((w+40)-w)+w,r.nextInt(h),r.nextInt(270-90)+90 }; break; case 3: posRange = new int[]{ 3,r.nextInt(w),r.nextInt(40)-40,r.nextInt(180) }; break; case 4: posRange = new int[]{ 4,r.nextInt(40)-40,r.nextInt(h),r.nextInt(180) }; break; } System.out.println(side); return posRange; } public void start() { setSize(500,500); setBackground(Color.BLACK); new Thread(this).start(); } public void run() { } public void update(Graphics g) { paint(g); } public void paint(Graphics e) { Graphics2D g = (Graphics2D) e; if(System.currentTimeMillis()%113==0) { x+=1; y+=1; } g.setColor(Color.BLUE); g.fillOval(x,y,20,20); repaint(); } } 

  1. 你需要调用super.paint(g); 在你的paint方法中,不要留下油漆文物。

  2. 切勿从paint方法中调用repaint()

  3. 不要像在update()那样显式调用paint ,而是调用reapaint()

  4. 只需从update()方法内部更新xy值,然后调用repaint()

  5. 您不需要在update()使用Graphics参数

  6. 您需要在循环中重复调用update() ,因为它会更新xy以及reapint()

  7. 如果你的类将成为Runnable ,那么你应该在run()方法中放入一些代码。 这可能是你应该拥有循环的地方


 import java.applet.Applet; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; public class circles extends Applet implements Runnable { int x = 0, y = 0; public void start() { setSize(500, 500); setBackground(Color.BLACK); new Thread(this).start(); } public void run() { while (true) { try { update(); Thread.sleep(50); } catch (InterruptedException ex) { } } } public void update() { x += 5; y += 6; repaint(); } public void paint(Graphics e) { super.paint(e); Graphics2D g = (Graphics2D) e; g.setColor(Color.BLUE); g.fillOval(x, y, 20, 20); } } 

附注

  • 为什么首先使用Applet。 如果必须,为什么要使用AWT Applet而不是Swing JApplet ? 升级的时间。

这是我在Swing中重做整个事情的方法,使用Swing Timer而不是循环和Thread.sleep ,就像你应该做的那样。

 import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.Timer; public class Circle extends JPanel{ private static final int D_W = 500; private static final int D_H = 500; int x = 0; int y = 0; public Circle() { setBackground(Color.BLACK); Timer timer = new Timer(50, new ActionListener(){ public void actionPerformed(ActionEvent e) { x += 5; y += 5; repaint(); } }); timer.start(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.BLUE); g.fillOval(x, y, 20, 20); } @Override public Dimension getPreferredSize() { return new Dimension(D_W, D_H); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { JFrame frame = new JFrame(); frame.add(new Circle()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } } 

  • 请参见如何使用Swing Timers

  • 请参阅使用Swing创建GUI

  • 这是更高级的例子供您查看和思考。

UPDATE

“问题是,这是一个JPANEL应用程序。我特别希望在网页上轻松使用applet。”

你仍然可以使用它。 只需使用JPanel。 取出main方法,而不是Applet,使用JApplet,只需将JPanel添加到applet中。 很简单。

 import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JApplet; import javax.swing.JPanel; import javax.swing.Timer; public class CircleApplet extends JApplet { @Override public void init() { add(new Circle()); } public class Circle extends JPanel { private static final int D_W = 500; private static final int D_H = 500; int x = 0; int y = 0; public Circle() { setBackground(Color.BLACK); Timer timer = new Timer(50, new ActionListener() { public void actionPerformed(ActionEvent e) { x += 5; y += 5; repaint(); } }); timer.start(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.BLUE); g.fillOval(x, y, 20, 20); } @Override public Dimension getPreferredSize() { return new Dimension(D_W, D_H); } } }