哇... JavaFx 2在游戏编程方面给我一个循环。我试图确定如何最好地接近玩家控制的精灵动画。 (即制造敌人和东西以及玩家的动画)。
我知道如何编写代码来读取spritesheet并在AS3或Java swing中设置一个游戏循环......但是我真的很难理解我的游戏中的动画循环应该如何交互无论是什么组成的FX,它都会呈现。
我研究了api。有一个TranslateTransition类。但与其他语言相比,这似乎过分了。而其他东西看起来完全基于界面或太有限。
我正在阅读Weaver的Pro JavaFx2 ...而且我无法复制那种编码风格。但是我可以看到它发现:)不知道是不是爱还是恨这个野兽。
有什么建议吗?
答案 0 :(得分:5)
阅读此博客文章:http://blog.netopyr.com/2012/03/09/creating-a-sprite-animation-with-javafx/
这是JavaFX精灵动画的最佳实现:)
答案 1 :(得分:2)
我在派对上有点晚了,但我想我会用JavaFX为sprite动画贡献我的解决方案。这是一个可以粘贴到您自己的项目中的类,使用ImageView显示精灵动画,动画与帧速率无关。
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));
}
}
}
使用以下内容实现此目的:
ImageViewSprite anim = new ImageViewSprite(ImageView, new Image("/pathToImage"), columns, rows, totalNumberOfFrames, FrameWidth, FrameHeight, FPS);
anim.start();