0

任何想法为什么我的椭圆形不向右移动?我有一个游戏循环,但不知何故,圆圈停留在它出现的位置,而不是每个循环向右移动 2 个像素。奇怪的是,它在实际绘画之前就进入了循环。但随后图形对象出现(在固定位置)。

public class GamePanel extends JPanel implements Runnable {

    public static int WIDTH = 1024;
    public static int HEIGHT = WIDTH / 16 * 9;
    private Thread t1;
    boolean running;
    private int FPS = 60;
    private long optimalTime = 1000 / FPS;
    private int heroX = 200;
    private int heroY = 200;


    public void addNotify(){
        Dimension size = new Dimension(WIDTH,HEIGHT);
        setPreferredSize(size);
        setFocusable(true);
        requestFocus();
        running = true;
        t1 = new Thread(this);
        t1.start();
    }



    public void paintComponent (Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.WHITE);
        g2.fillRect(0, 0, WIDTH, HEIGHT);
        g2.setColor(Color.BLACK);
        g2.fillOval(heroX, heroY, 50, 50);
        g2.dispose();
    }


    public void run() {
        long startTime;
        long passedTime;
        long waitTime;
        while (running){
            startTime = System.nanoTime();
            System.out.println("Runs");
            update();
            draw();
            repaint();
            passedTime = System.nanoTime() - startTime;
            waitTime = optimalTime - passedTime / 1000000;
            try {
                if (waitTime <= 0){
                    waitTime = 2;
                }
                Thread.sleep(waitTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }



    private void draw() {


    }



    private void update() {

        heroX += 2;

    }

}
4

2 回答 2

1

您应该使用摇摆计时器而不是尝试使用线程。如果您需要在后台做一些耗时的事情,请使用SwingWorkers。如果您真的需要,可以使用您自己的线程与swing与秋千。

public class GamePanel extends JPanel {
    private static final int DELAY = 1000 / 60;
    private final Timer timer;
    // ...

    private int heroX = 200;
    private int heroY = 200;

    public GamePanel() {
        timer = new Timer(DELAY, new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                update();
                repaint();
            }
        });
        // ...
    }

    // No need to make this public
    @Override
    protected void paintComponent (Graphics g) {
        // ...
    }

    @Override
    public Dimension getPreferredSize() {
        // Overriding is cleaner than using set*Size(). Search old questions to see why
    }

    public void startAnimation() {
         timer.start();
    }

    public void stopAnimation() {
         timer.stop();
    }

    // Remove addNotify() and run()
}
于 2013-07-31T10:30:29.747 回答
0

在阅读和测试之后,我只是想这样做。它按预期工作,即使 paintComponent 在 EDT 之外。

public class GamePanel extends JPanel implements Runnable {

    public static int WIDTH = 1024;
    public static int HEIGHT = WIDTH / 16 * 9;
    private int cordX = WIDTH / 2;
    private Thread t1;
    private boolean running = true;

    public void addNotify() {
       super.addNotify();
       Dimension size = new Dimension (WIDTH, HEIGHT);
       setPreferredSize(size);
       t1 = new Thread(this);
       t1.start();
     }

    public void paintComponent(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, WIDTH, HEIGHT);
        g.setColor(Color.BLACK);
        g.fillOval(cordX, HEIGHT /2 , 20, 20);
    }

    public void run() {
        while(running) {
            cordX += 2;
            repaint();
            try {
                    Thread.sleep(17);
                } catch (InterruptedException e) {
                    e.printStackTrace();
            }
        }  
}
于 2013-08-01T10:19:17.930 回答