xPosition更新时,图形对象不会更新

时间:2015-01-03 20:13:26

标签: java render increment

我正在尝试创建一个行星(蓝色圆圈),并在我更新x位置时移动它。这是主要的课程。

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JFrame;

public class Main extends Canvas implements Runnable{

    public int width = 1400;
    public int height = (width/16)* 9;

    Dimension dim = new Dimension(width, height);

    JFrame frame;

    boolean running;

    NewBody earth;

    public Main(){
        this.setPreferredSize(dim);
        this.setBackground(Color.BLACK);
    }

    public void start(){
        running = true;

        Thread thread = new Thread(this, "display");
        thread.start();
    }

    public void run(){
        long startTime = System.currentTimeMillis();
        double conv = Math.pow(10, 3);

        while(running){     
            long now = System.currentTimeMillis();
            if((now-startTime)/conv >= 1){
                earth.incXPos();
                startTime = now;
                return;
            }   

            update();
        }
    }

    public void update(){
        repaint();

    }

    public void stop(){
        running = false;
    }

    public void paint(Graphics g){
        Graphics2D g2d = (Graphics2D)g;
        g2d.setColor(Color.BLUE);
        g2d.fillOval(earth.xPos,earth.yPos, earth.radius*2, earth.radius*2);

    }

    public static void main(String args[]){
        Main main = new Main();

        main.frame = new JFrame();
        main.frame.setResizable(false);
        main.frame.add(main);
        main.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        main.frame.pack();

        main.frame.setVisible(true);

        main.earth = new NewBody(0, 0,0, 50);

        main.start();
    }
}

这是NewBody的蓝图,我正在创建"地球"

public class NewBody {

    Main main = new Main();

    public int xOrigo = 1400/2;
    public int yOrigo = 800/2;

    public double mass;
    public double velocity;
    public int xPos;
    public int yPos;
    public double force;
    public double vectorAngle;
    public double fx;
    public double fy;
    public double acceleration;
    public int radius; 

    public NewBody(double mass, int xPos, int yPos, int radius){
        this.mass = mass;
        this.xPos = xOrigo + xPos - radius;
        this.yPos = yOrigo + yPos - radius;
        this.radius = radius;
    }

    public void incXPos(){
        this.xPos++;
    }

问题在于,当我运行程序时,蓝色圆圈只是保持在初始化的相同位置。它只是闪烁得非常快,没有别的事情发生。我对编码很新,我似乎没有收到任何错误信息,因此我不知道如何继续。我已经被困在这几个小时了。

你有什么想法吗?

1 个答案:

答案 0 :(得分:3)

return;方法中的run()语句导致方法短路退出,因此在调用incXPos()一次后立即退出。即使在调用update()之前也会发生这种情况,因此永远不会调用repaint()

我做的事情有点不同但是:

  • 我在JPanel中绘图
  • 我在其paintComponent方法中绘图。
  • 我使用Swing Timer而不是Thread来进行动画循环。
  • 我一定要打电话给我超越的超级paintComponent(g)

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class SimpleAnimation extends JPanel {
   private static final int PREF_W = 1400;
   private static final int PREF_H = (PREF_W * 9) / 16; // do int mult **first**
   private static final int TIMER_DELAY = 13;
   private NewBody earth = new NewBody(0, 0, 0, 50);

   public SimpleAnimation() {
      new Timer(TIMER_DELAY, new TimerListener()).start();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;

      // to allow for smooth graphics
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

      g2d.setColor(Color.BLUE);
      g2d.fillOval(earth.xPos, earth.yPos, earth.radius * 2, earth.radius * 2);
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         earth.incXPos();
         repaint();
      }
   }

   private static void createAndShowGui() {
      SimpleAnimation mainPanel = new SimpleAnimation();

      JFrame frame = new JFrame("SimpleAnimation");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class NewBody {

   // !! Main main = new Main();

   public int xOrigo = 1400 / 2;
   public int yOrigo = 800 / 2;

   public double mass;
   public double velocity;
   public int xPos;
   public int yPos;
   public double force;
   public double vectorAngle;
   public double fx;
   public double fy;
   public double acceleration;
   public int radius;

   public NewBody(double mass, int xPos, int yPos, int radius) {
      this.mass = mass;
      this.xPos = xOrigo + xPos - radius;
      this.yPos = yOrigo + yPos - radius;
      this.radius = radius;
   }

   public void incXPos() {
      this.xPos++;
   }
}