使用JavaFX制作ImageView精灵动画

5
我正在尝试使用JavaFX在登录窗口(stage)中创建一个精灵动画,一旦用户获取登录和密码信息,该动画将播放。我尝试使用Michael Heinrichs在他的博客文章中发布的类来创建JavaFX精灵动画,但我无法使其正常工作,主要是因为我不知道如何在ImageView内创建此动画,而不使用start方法(这在我的情况下也无法正常工作)。
以下是我在Login Stage的FXML文件中拥有的代码:
<GridPane alignment="CENTER" hgap="10.0" vgap="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="crud.controller.MainController">
    <padding>
        <Insets bottom="25.0" left="25.0" right="25.0" top="25.0" />
    </padding>
    <children>
        <ImageView fx:id="loginAnimationImageView" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.columnSpan="2" GridPane.rowIndex="0">
            <image>
                <Image url="@../assets/shop-sprite.png" />
            </image>
        <viewport>
            <Rectangle2D height="130.0" width="131.0" />
        </viewport>
        </ImageView>
        <Label text="Usuario" GridPane.columnIndex="0" GridPane.halignment="RIGHT" GridPane.rowIndex="2" />
        <TextField fx:id="loginTextField" onAction="#onEnterTextFieldAction" GridPane.columnIndex="1" GridPane.rowIndex="2" />
        <Label text="Contraseña" GridPane.columnIndex="0" GridPane.rowIndex="3" />
        <PasswordField fx:id="passwordTextField" onAction="#onEnterPasswordFieldAction" GridPane.columnIndex="1" GridPane.rowIndex="3" />
        <Button fx:id="loginButton" onAction="#loginButtonAction" text="Ingresar" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.rowIndex="5" />
    </children>
</GridPane>

在控制器类中,我尝试创建一个启动方法,但首先,我不知道如何在舞台打开时同时启动它,第二,当我尝试从按钮调用该方法时,它会尝试渲染图像(修改所需的空间),但它不显示任何内容。

以下是代码:

@FXML private void launchAnimation() {
    loginAnimationImageView = new ImageView(IMAGE);
    loginAnimationImageView.setViewport(new Rectangle2D(OFFSET_X, OFFSET_Y, WIDTH, HEIGHT));

    final Animation animacion = new SpriteAnimation(
            loginAnimationImageView,
            Duration.millis(1000.0),
            COUNT, COLUMNS,
            OFFSET_X, OFFSET_Y,
            WIDTH, HEIGHT
    );

    animacion.setCycleCount(Animation.INDEFINITE);
    animacion.play();
}

最后,这里是常量声明:

private static final Image IMAGE = new Image("https://i.cloudup.com/1VA2FCnqY6-2000x2000.png");
private static final int COLUMNS  = 4;
private static final int COUNT    = 12;
private static final int OFFSET_X = 0;
private static final int OFFSET_Y = 0;
private static final int WIDTH    = 131;
private static final int HEIGHT   = 125;

目前的登录界面如下图所示,我想为它添加一个动画logo:

enter image description here

请问有谁能帮助我理解如何在这种情况下使用image view?

是否可以使用ImageView来创建这种效果,还是说我在浪费时间?


2
请参见如何在JavaFX中显示图像的特定部分。有两种方法可以使用视口,类似于您提到的链接,还可以使用剪辑。 - Uluk Biy
1个回答

4
我做到了,我使用JavaFX和这个精灵图片做出了简单的动画效果,如果您也想实现类似的效果,我想与您分享。

这是结果 (YouTube)

首先,我创建了登录阶段的FXML文件,并使用此代码(请记得为您的控制器类和图像文件设置正确的位置):

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>

<GridPane alignment="CENTER" hgap="10.0" vgap="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="package.Controller">
    <padding>
        <Insets bottom="25.0" left="25.0" right="25.0" top="25.0" />
    </padding>
    <children>
        <ImageView fx:id="loginAnimationImageView" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.columnSpan="2" GridPane.rowIndex="0">
            <image>
                <Image url="@route/to/shop-sprite.png" />
            </image>
        <viewport>
            <Rectangle2D minX="0" minY="0" height="130.0" width="130.0" />
        </viewport>
        </ImageView>
        <Label text="Usuario" GridPane.columnIndex="0" GridPane.halignment="RIGHT" GridPane.rowIndex="2" />
        <TextField fx:id="loginTextField" onAction="#onEnterTextFieldAction" GridPane.columnIndex="1" GridPane.rowIndex="2" />
        <Label text="Contraseña" GridPane.columnIndex="0" GridPane.rowIndex="3" />
        <PasswordField fx:id="passwordTextField" onAction="#onEnterPasswordFieldAction" GridPane.columnIndex="1" GridPane.rowIndex="3" />
        <Button fx:id="loginButton" onAction="#loginButtonAction" text="Ingresar" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.rowIndex="5" />
    </children>
</GridPane>

现在我们需要使用由Michael Heinrichs创建的动画类来设置我们的控制器,我已经在上面的问题中提供了链接。

注意:这个动画将与登录按钮一起启动,一旦登录和密码信息得到验证,因此您需要在自己的应用程序中设置代码来完成此操作。

那么这是控制器的代码:

public class MainController {
    private static final int COLUMNS  = 4;
    private static final int COUNT    = 12;
    private static final int OFFSET_X = 0;
    private static final int OFFSET_Y = 0;
    private static final int WIDTH    = 130;
    private static final int HEIGHT   = 130;
    @FXML private ImageView loginAnimationImageView;
    @FXML private TextField loginTextField;
    @FXML private PasswordField passwordTextField;
    @FXML private Button loginButton;

    @FXML protected void onEnterTextFieldAction(ActionEvent actionEvent) {
}

    @FXML protected void onEnterPasswordFieldAction(ActionEvent actionEvent) {
}

    @FXML protected void loginButtonAction(ActionEvent actionEvent) {
        final Animation animation = new SpriteAnimation(
                loginAnimationImageView,
                Duration.millis(400.0),
                COUNT, COLUMNS,
                OFFSET_X, OFFSET_Y,
                WIDTH, HEIGHT
        );

        animation.setCycleCount(1);
        animation.play();
    }
}

就是这样,您不需要做任何其他事情,即可为您的任何JavaFX应用程序创建这个简单的动画。享受它吧!


3
SpriteAnimation使用ImageView的setViewport()方法来切换不同的精灵图,经过一些实验,我发现使用单独的Image(setImage())比使用setViewport()具有更好的性能效果,提高了超过100%。 - Waverick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接