1

我目前正在用 Java 编写一个横向卷轴,但我注意到移动的背景看起来并不流畅,而是结结巴巴。我通过将每帧向左偏移几个像素来实现背景的移动,每秒 60 个滴答声。

我不知道增加滴答声是否会解决这个问题,但这肯定会使一切复杂化。

我将代码分解为这个来演示这个问题。当然,我真正的程序要大得多。

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class Background extends JPanel implements Runnable{

    private BufferedImage img1;
    private BufferedImage img2;

    private static final int OFFSET = 10;

    private int x1;
    private int x2;

    private static final int WIDTH = 500;

    private Thread thread;
    private boolean running;

    public Background()
    {
        super();
        setSize(WIDTH,500);

        x1 = 0;
        x2 = WIDTH;
        running = false;

        try {
            img1 = ImageIO.read(Background.class.getResource("walltest1.png"));
            img2 = ImageIO.read(Background.class.getResource("walltest2.png"));
        } catch (IOException ex) {
            System.out.println("Image not found");
        }
        setVisible(true);
        start();
    }

    @Override
    public void run(){

        long lastTime = System.nanoTime();
        double nsPerTick = 1000000000D/60D; //1 Sec. = 1 billion nano seconds. Divided by 60 = 60 'frames' per sec.

        int ticks = 0;
        int frames = 0;
            long lastTimer = System.currentTimeMillis();
            double delta = 0;
        while(running)
        {
            long now = System.nanoTime();
            delta += (now-lastTime)/nsPerTick; //the time that has passed divided by the ns that need to pass till it ticks.
            lastTime = now;

            if(delta >=1){
                ticks++;
                tick();
                delta -= 1 ;
            }

            try {
                Thread.sleep(2);
            } catch (InterruptedException ex) {
                System.out.println(ex);
            }

            frames++;
            repaint();

            if(System.currentTimeMillis() - lastTimer >= 1000)
            {
                lastTimer +=1000;
                System.out.println(ticks + " ticks, " + frames + " frames");
                frames = 0;
                ticks = 0;

            }
        }
    }

    private void tick()
    {
        x1 -= OFFSET;
        x2 -= OFFSET;

        if(x1 <= -WIDTH) x1 = x2 + img2.getWidth();
        if(x2 <= -WIDTH) x2 = x1 + img2.getWidth();
    }

    public synchronized void start()
    {
        thread = new Thread(this);
        running=true;
        thread.start();
    }
    @Override
    public void paint(Graphics g)
    {
        super.paint(g);

        g.drawImage(img1, x1,0, null);
        g.drawImage(img2, x2, 0, null);
        g.dispose();
    }
    public synchronized void stop(){}
}
4

0 回答 0