我有一个行星模型(下),并在屏幕中心绘制太阳。然后,我使用新的线程绘制行星。行星运动太快,并不意味着它是绕一圈运动。我试图改变线程的睡眠时间和行星的速度,但这并不重要-行星运动太快。速度> 3-速度太快。

我需要结果:行星运动缓慢,我可以用她的速度(1、3、5、10)来控制行星的速度。角度(行星的位置)在少量(1、3、5度-速度)上每秒变化1次

public class Planet
{
    private String name;
    private int id;
    private double radius = 1.0;
    private double radiusOrbit = 5.0;
    private double velocity = 1;
    private Color color;
    private int angle = 0;
    private String parent;

    public Planet(String name, int id, double rad, double radOrbit, double velocity, Color color)
    {
        this.name = name;
        this.id = id;
        this.radius = rad;
        this.radiusOrbit = radOrbit;
        this.velocity = velocity;
        this.color = color;
   }
...getters and setters
}


主班

public class ShowCosmos2 {
    public static void main(String[] args)
    {
        JFrame frame = new PlanetsFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

class PlanetsFrame extends JFrame
{

    private int width = Toolkit.getDefaultToolkit().getScreenSize().width;
    private int height = Toolkit.getDefaultToolkit().getScreenSize().height;
    public PlanetsFrame()
    {
        setSize(width, height);
        setTitle("Planets");

        setContentPane(new PlanetsCanvas(width, height));
        Container contentPane = getContentPane();
        contentPane.setBackground(Color.BLACK);
    }
}

class PlanetsCanvas extends JPanel
{
    private int width, height;
    private int centerX = 0;
    private int centerY = 0;
    private Thread runner;
    private boolean running = false;
    Planet[] planets = {
        new Planet("Venera", 1, 5.0, 50.0, 1, Color.GREEN),
        new Planet("Mercury", 1, 3.0, 75.0, 1.5, Color.ORANGE),
        new Planet("Earth", 1, 6.0, 100.0, 2, Color.BLUE),
        new Planet("Jupiter", 1, 12.0, 150.0, 1, Color.RED)
    };
    public PlanetsCanvas(int w, int h)
    {
        width = w;
        height = h;
        centerX = (int)(w/2);
        centerY = (int)(h/2);
    }

    protected void drawFrame(Graphics g)
    {
        //Sun
            g.setColor(Color.YELLOW);
            g.fillOval(width/2 - 25, height/2 - 25, 50, 50);
            for (int i = 0; i < planets.length; i++)
            {
                Planet p = planets[i];
                g.setColor(p.getColor());
                int newX = (int)(centerX + Math.cos(p.getAngle())*p.getRadiusOrbit());
                int newY = (int)(centerY - Math.sin(p.getAngle())*p.getRadiusOrbit());
                g.fillOval((int)(newX-p.getRadius()),
                        (int)(newY-p.getRadius()),
                        (int)p.getRadius()*2, (int)p.getRadius()*2);
                //int angle = (int)(p.getAngle() + p.getVelocity());
                //if (angle >= 360) angle = 0;
                //p.setAngle(angle);
            }
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        drawFrame(g);
        startAnimation();
    }

    public void startAnimation() {
        runner = new Thread() {
            public void run() {
                try {
                    while (!Thread.interrupted()) {
                        repaint();
                        for(int i=0; i<planets.length; i++)
                        {
                            Planet p = planets[i];
                            int angle = (int)(p.getAngle() + p.getVelocity());
                            if (angle >= 360) angle = 0;
                            p.setAngle(angle);
                        }
                        Thread.sleep(500);
                    }
                } catch (Exception e) {

                }
            }
        };
        runner.start();
        running = true;
    }
}

最佳答案

最重要的是-不要从paintComponent内开始动画。 paintcomponent方法将一遍又一遍地被调用,这意味着当只需要一个时,您将不必要地创建越来越多的动画线程。更糟糕的是,您无法完全控制何时或什至是否调用paintComponent。因此,请一次启动动画线程,并且可能在类的构造函数中启动。

07-26 08:34