4

哇... JavaFx 2 在游戏编程方面让我陷入了困境。我正在尝试确定如何最好地处理玩家控制的精灵动画。(即制造敌人和事物以及玩家动画)。

我知道如何编写代码来读取 spritesheet 并在 AS3 或 Java swing 中设置游戏循环......但是我很难理解我的游戏中的动画循环应该如何与任何组件交互FX 就是渲染。

我研究过api。有一个 TranslateTransition 类。但与其他语言相比,它似乎太过分了。其他的 eberything 看起来完全基于界面或过于有限。

我正在阅读 Weaver 的 Pro JavaFx2 ......而且我在复制这种编码风格时遇到了麻烦。但我可以阅读它找到:) 不知道是爱还是恨这个野兽呢。

有什么建议么?

4

2 回答 2

5

阅读此博客条目:http: //blog.netopyr.com/2012/03/09/creating-a-sprite-animation-with-javafx/

这是有史以来最好的 JavaFX sprite 动画实现 :)

于 2012-05-22T21:10:15.707 回答
3

我参加这个聚会有点晚了,但我想我会为使用 JavaFX 的精灵动画贡献我的解决方案。这是一个您可以粘贴到您自己的项目中的类,以使用 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();
于 2014-03-17T22:44:32.067 回答