Wow... JavaFx 2 has thrown me for a loop when it comes to game programming. I am trying to etermine how best to approach player controlled sprite animation. (ie. making enemies and things and the player animate).
I know how to write code to read a spritesheet and set up a game loop in AS3 or Java swing... but it I'm having a real tough time wrapping my head around how the animation loop in my game should interact with whatever component of FX it is that renders.
I've studied the api. There is a TranslateTransition class. But it seems excessive compared to other languages. And eberything else looks completely interface based or just too limited.
I'm reading Pro JavaFx2 by Weaver... and man am I having trouble replicating that coding style. But I can read it find :) Don't know whether to love or hate this beast yet.
Any suggestions?
Read this blog entry: http://blog.netopyr.com/2012/03/09/creating-a-sprite-animation-with-javafx/
This is best realization of JavaFX sprite animation ever :)
I'm a little late to the party on this one, but figured I'd contribute my solution to sprite animation with JavaFX. Here's a class you can paste into your own projects to display a sprite animation using ImageView, the animation is frame-rate independent.
import javafx.animation.AnimationTimer;
import javafx.geometry.Rectangle2D;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
public class ImageViewSprite extends AnimationTimer {
private final ImageView imageView; //Image view that will display our sprite
private final int totalFrames; //Total number of frames in the sequence
private final float fps; //frames per second I.E. 24
private final int cols; //Number of columns on the sprite sheet
private final int rows; //Number of rows on the sprite sheet
private final int frameWidth; //Width of an individual frame
private final int frameHeight; //Height of an individual frame
private int currentCol = 0;
private int currentRow = 0;
private long lastFrame = 0;
public ImageViewSprite(ImageView imageView, Image image, int columns, int rows, int totalFrames, int frameWidth, int frameHeight, float framesPerSecond) {
this.imageView = imageView;
imageView.setImage(image);
imageView.setViewport(new Rectangle2D(0, 0, frameWidth, frameHeight));
cols = columns;
this.rows = rows;
this.totalFrames = totalFrames;
this.frameWidth = frameWidth;
this.frameHeight = frameHeight;
fps = framesPerSecond;
lastFrame = System.nanoTime();
}
@Override
public void handle(long now) {
int frameJump = (int) Math.floor((now - lastFrame) / (1000000000 / fps)); //Determine how many frames we need to advance to maintain frame rate independence
//Do a bunch of math to determine where the viewport needs to be positioned on the sprite sheet
if (frameJump >= 1) {
lastFrame = now;
int addRows = (int) Math.floor((float) frameJump / (float) cols);
int frameAdd = frameJump - (addRows * cols);
if (currentCol + frameAdd >= cols) {
currentRow += addRows + 1;
currentCol = frameAdd - (cols - currentCol);
} else {
currentRow += addRows;
currentCol += frameAdd;
}
currentRow = (currentRow >= rows) ? currentRow - ((int) Math.floor((float) currentRow / rows) * rows) : currentRow;
//The last row may or may not contain the full number of columns
if ((currentRow * cols) + currentCol >= totalFrames) {
currentRow = 0;
currentCol = Math.abs(currentCol - (totalFrames - (int) (Math.floor((float) totalFrames / cols) * cols)));
}
imageView.setViewport(new Rectangle2D(currentCol * frameWidth, currentRow * frameHeight, frameWidth, frameHeight));
}
}
}
Implement this with the following:
ImageViewSprite anim = new ImageViewSprite(ImageView, new Image("/pathToImage"), columns, rows, totalNumberOfFrames, FrameWidth, FrameHeight, FPS);
anim.start();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With