I have different sprites that I want to render at different speeds by changing to the next frame in the spritesheet if a delta time has passed. The problem is I have no idea how to get this delta, I cannot measure it inside the frameUpdate method of the sprite because it is called all the time inside my gameloop. I cannot measure it inside the gameloop because the game loops condition is while(game.isRunning()).
Essentially:
1) Somewhere in code, create animatedsprite with framedelay 250ms.
In gameloop:
2) Measure time after updating
3) Pass delta to animatedsprite
4) In animatedSprite, check if 250 ms has passed
5) Has 250 ms passed? Then draw next frame
Stuck on 3). I am currently solving this by clever use of math, if a multiple of the framedelay has passed then I curentFrame++ but since the Thread.sleep in the gameloop is not continious (1 ms resolution but usually determined by fps, eg if 100 fps then 10 ms resolution) this will not work if I do not provide a margin, my current margin is 10 ms. This assumes that the game MUST run under 100 fps and that there is no sprite that is rendered above 100 fps (framedelay < 10 ms).
Any solutions? Current SCCE:
Sprite
public class Animated implements Renderable {
private ArrayList<BufferedImage> sheet;
private int cols;
private int rows;
private int x;
private int y;
private int frameDelay;
private int currentFrame;
private int lastFrame;
private BufferedImage currentImage;
public Animated(ArrayList<BufferedImage> spritesheet, int cols,
int rows, int frameDelay) {
this.sheet = spritesheet;
this.cols = cols;
this.rows = rows;
this.frameDelay = frameDelay;
this.lastFrame = sheet.size() - 1;
this.currentImage = sheet.get(0);
}
private void frameUpdate(int deltaTime) {
System.out.println(deltaTime % frameDelay);
if ((deltaTime % frameDelay) < 10) {
if (currentFrame == lastFrame) {
currentFrame = 0;
}
else {
currentFrame++;
}
currentImage = sheet.get(currentFrame);
}
}
@Override
public void render(Graphics2D g) {
}
@Override
public void setPosition(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public void render(Graphics2D g, int deltaTime) {
frameUpdate(deltaTime);
g.drawImage(currentImage, x, y, null);
}
}
Render in loop:
public void render() {
Renderable bahamut = new Animated(images.get("bahamutANIMATED"), 4, 4,
250);
bahamut.setPosition(0, 500);
Renderable bahamut2 = new Animated(images.get("bahamutANIMATED"), 4, 4,
5000);
bahamut2.setPosition(0, 0);
long t0 = System.currentTimeMillis();
while (true) {
clearScreen();
long t1 = System.currentTimeMillis();
int delta = (int) (t1 - t0);
bahamut.render(g, delta);
bahamut2.render(g, delta);
showBuffer();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}