我目前正在用 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(){}
}