Java小程序重绘一个动圈 [英] Java applet repaint a moving circle

查看:30
本文介绍了Java小程序重绘一个动圈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚从 Pygame 迁移过来,所以小程序中的 Java 2D 对我来说有点新鲜,尤其是在重新绘制屏幕时.在 pygame 中,您可以简单地执行 display.fill([1,1,1]) 但如何在 Java 小程序中执行此操作?我理解 repaint() 的使用,但这并没有清除屏幕 - 任何移动的对象都不会从屏幕上移除",所以你只会得到一长串画圆圈.

I've just moved over from Pygame so Java 2D in an applet is a little new to me, especially when it comes to repainting the screen. In pygame you can simply do display.fill([1,1,1]) but how do I do this in an applet in Java? I understand the use of repaint() but that doesn't clear the screen - any moving object is not 'removed' from the screen so you just get a long line of painted circles.

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

Here's my code that I've been testing with:

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. 您需要在您的 paint 方法中调用 super.paint(g);,以免留下油漆痕迹.

  1. You need to call super.paint(g); in your paint method, as to not leave paint artifacts.

永远不要从 paint 方法内部调用 repaint()

Never call repaint() from inside the paint method

不要像在 update() 中那样显式调用 paint,当您打算调用 reapaint()

Don't explicitly call paint, as you do in update(), when you mean to call reapaint()

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

just update the x and y values from inside the update() method, then call repaint()

您不需要在 update()

您需要在循环中的某处重复调用 update(),因为它会更新 xyreapint()s

You need to call update() somewhere repeatedly in a loop, as it updates the x and y and reapint()s

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

If your class is going to be a Runnable, then you should put some code in the run() method. That's probably where you should have your loop

<小时>

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);

    }
}

<小时>

附注

  • 首先为什么要使用小程序.如果必须,为什么要使用 AWT Applet 而不是 Swing JApplet?是时候升级了.
  • Why use Applets in the first place. If you must, why use AWT Applet and not Swing JApplet? Time for an upgrade.

这是我如何在 Swing 中重做整个事情,使用 Swing Timer 而不是循环和 Thread.sleep,如你应该做的.

Here's how I'd redo the whole thing in Swing, using a Swing Timer instead of a loop and Thread.sleep, as you should be doing.

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 创建 GUI

    更新

    问题是,这是一个 JPANEL 应用程序.我特别想让小程序在网页上易于使用."

    "Problem is, that's a JPANEL application. I specifically want to make an applet easily usable on a web page. "

    你仍然可以使用它.只需使用 JPanel.取出 main 方法,而不是 Applet,使用 JApplet 并将 JPanel 添加到您的小程序中.就这么简单.

    You can still use it. Just use the JPanel. Take out the main method, and instead of Applet, use a JApplet and just add the JPanel to your applet. Easy as that.

    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);
            }
    
        }
    }
    

    这篇关于Java小程序重绘一个动圈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆