使用java.swing.Timer和java.util.Timer以及Thread.sleep()进行不均匀的时间步长

时间:2015-04-05 22:47:10

标签: java animation timer sleep

我无法理解为什么这个Timer会以锯齿状动画制作动画。这是一个依赖于平台的问题吗?我正在使用这种动画编写2D游戏,并且对不均匀的帧速率感到沮丧。以下是简化示例的代码:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;

import javax.swing.JPanel;

public class AnimationTest extends JPanel
{
    private static final long serialVersionUID = 1L;
    private Point location = new Point(0, 300);
    private int speed = 3;

    public AnimationTest()
    {
        setPreferredSize(new Dimension(800, 600));
    }

    public void timeStep()
    {
        move();
        repaint();
        currentTime = System.nanoTime();
        System.out.println(currentTime - previousTime);
        previousTime = currentTime;
    }

    private void move()
    {
        location.x += speed;
        if(location.x >= 800) location.x = 0;
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g;
        super.paintComponent(g2d);
        g2d.fillOval(location.x, location.y, 40, 40);
    }
}

这是主要方法:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.WindowConstants;

public class AnimationTestMain
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame("Test");
        final AnimationTest test = new AnimationTest();
        frame.add(test);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);

        int animationMethod = 0;

        if(animationMethod == 0)
        {
            new javax.swing.Timer(10, new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent e)
                {
                    test.timeStep();
                }
            }).start();
        }
        else if(animationMethod == 1)
        {
            Thread thread = new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    while(true)
                    {
                        test.timeStep();
                        try
                        {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {}
                    }
                }
            });
            thread.start();
        }
        else if(animationMethod == 2)
        {
            java.util.Timer timer = new Timer();
            timer.scheduleAtFixedRate(new TimerTask()
            {
                @Override
                public void run()
                {
                    while(true)
                    {
                        test.timeStep();
                        try
                        {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {}
                    }
                }
            }, 0, 10);
        }
    }
}

修改animationMethod变量不会改变很多结果。您可以在纳秒打印输出中看到不均匀的帧速率。救命啊!

1 个答案:

答案 0 :(得分:0)

摇摆计时器是你得到的最不经常的选择。

还有其他2个选项:

  • 效用计时器(中等精度)
  • 自己的线程(最高精度)

查看this link

如果您选择创建自己的主题,请查看游戏循环this tutorial