我目前正在制作侧卷轴,我一直致力于移动背景。这是我用来管理它的运动的类:
package game;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import framework.GClock;
public class BackgroundManager {
public BufferedImage background;
public BufferedImage[] movingImages;
private final int y=4,x=2;
public final int scale = 3;
private float[] speed;
private Rectangle[][] rects;
private float speedScale =150f;
public BackgroundManager() {
try {
URL bg = BackgroundManager.class
.getResource("/resources/background.png");
background = ImageIO.read(bg);
URL[] urls = new URL[4];
urls[0] = BackgroundManager.class
.getResource("/resources/mountainBackground.png");
urls[1] = BackgroundManager.class
.getResource("/resources/mountainForeground.png");
urls[2] = BackgroundManager.class
.getResource("/resources/treesBackground.png");
urls[3] = BackgroundManager.class
.getResource("/resources/treesForeground.png");
movingImages = new BufferedImage[4];
for (int i = 0; i < y; i++) {
movingImages[i] = ImageIO.read(urls[i]);
}
int bgw = background.getWidth()*scale;
speed = new float[4];
for (int i = 0; i < y; i++) {
speed[i] = speedScale * (movingImages[i].getWidth()*scale
/ bgw-1);
System.out.println(speed[i]);
// maybe use
// Image.getScaledInstance(scaledWidth,scaledHeight,Image.SCALE_DEFAULT);
}
rects = new Rectangle[x][y];
for (int i = 0; i < y; i++) {
rects[0][i] = new Rectangle(0, 0,
movingImages[i].getWidth()*scale,
movingImages[i].getHeight()*scale);
rects[1][i] = new Rectangle(rects[0][i].width,
0, movingImages[i].getWidth()*scale,
movingImages[i].getHeight()*scale);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void update(GClock clock) {
float dt = clock.getElapsedTime();
for (int i = 0; i < y; i++) {
if (rects[0][i].x + rects[0][i].width < -10)
rects[0][i].x = rects[1][i].x + rects[1][i].width;
if (rects[1][i].x + rects[1][i].width < -10)
rects[1][i].x = rects[0][i].x + rects[0][i].width;
}
for (int i = 0; i < y; i++) {
rects[0][i].x -= speed[i] * dt;
rects[1][i].x -= speed[i] * dt;
}
}
public void drawBackground(Graphics2D g) {
//static background
g.drawImage(background, 0, 0, background.getWidth() * scale,
background.getHeight() * scale, null);
//other layers
for (int i = 0; i < y; i++) {
g.drawImage(movingImages[i], rects[0][i].x, 0,
rects[0][i].width,
rects[0][i].height, null);
g.drawImage(movingImages[i], rects[1][i].x, 0,
rects[1][i].width,
rects[1][i].height, null);
}
/*
// background
g.drawImage(background, 0, 0, background.getWidth() * scale,
background.getHeight() * scale, null);
// mountainBackground
g.drawImage(mountainBackground, (int) (-speed[0] * dt), 0,
mountainBackground.getWidth() * scale,
mountainBackground.getHeight() * scale, null);
// mountainForeground
g.drawImage(mountainForeground, (int) (-speed[1] * dt), 0,
mountainForeground.getWidth() * scale,
mountainForeground.getHeight() * scale, null);
// treesBackground
g.drawImage(treesBackground, (int) (-speed[2] * dt), 0,
treesBackground.getWidth() * scale, treesBackground.getHeight()
* scale, null);
// treesForeground
g.drawImage(treesForeground, (int) (-speed[3] * dt), 0,
treesForeground.getWidth() * scale, treesForeground.getHeight()
* scale, null);
*/
}
}
GClock
是我用来管理时间的课程,clock.getElapsedTime()
是上次更新 - &gt; draw-&gt;重绘 - &gt;睡眠周期所花费的时间。
出于某种原因,不是将第一张图像移动到下一张图像的右侧以模拟连续背景,而是this。在剪辑中,下一层加速直到它到达屏幕的左侧,然后匹配最后一层的速度。我已经尝试删除切换边界矩形位置的代码块,我花了大约一个小时来试图解决这个问题,但没有运气。我做错了什么?
编辑:以下是GClock的相关字段:
private long startTime;
private long dt;
private long lastTime;
private float targetTime;
private boolean isFpsCapped;
public GClock(){
startTime=lastTime=System.currentTimeMillis();
targetTime=1f/60f;
isFpsCapped=true;
}
protected void update(){
this.dt=System.currentTimeMillis()-lastTime;
this.lastTime=System.currentTimeMillis();
}
public float getElapsedTime(){
return (float)dt/1000f;
}
这是游戏循环:
while(isRunning){
clock.update();//calculates the amount of time that the last game loop took and prepares for the next clock.update() call.
if(!isPaused){
this.update(clock);//update is an abstract method that is implemented into child classes. For this instance, it only contains BackgroundManager.update(clock);
this.render(clock);//render is a method that manages the game's Graphics2D object, and calls this.draw(), which, like update(), is an abstract method called only by implementations of this class.
this.paintScreen();//repains the screen
}
if(clock.isFpsCapped()){
//thread.sleep(millis);
try {
Thread.sleep(clock.calculateSleepTime());//makes the thread sleep for a certain amount of time, so that the amount of time the gameloop took + calculateSleepTime() = some target time (in this case, it tries to keep the game at about 60 fps.)
} catch (InterruptedException e) {
e.printStackTrace();
}
}//end of if statement
}