Sprite animations on ImageView (JavaFX)
Animacje wykorzystujące arkusze duszków (sprite sheets) są najczęściej używane na stronach internetowych. Wczytywanie znacznej liczby małych obrazków wymaga sporej ilości operacji i/o, a użycie tej techniki pozwala na przyśpieszenie ładowania się strony.
Tutaj dla wprawy pokazuję użycie takiej animacji na JavaFX ImageView.
module-info.java
module m2serialanimations { requires jdk.jsobject; requires java.desktop; requires java.logging; requires java.net.http; requires java.scripting; requires java.sql; requires javafx.base; requires javafx.controls; requires javafx.graphics; requires javafx.fxml; requires javafx.media; requires javafx.swing; requires javafx.swt; requires javafx.web; exports p1_javafx_animations to javafx.graphics, javafx.web; exports p2_sprite_animations to javafx.graphics, javafx.web; exports utils to javafx.graphics, javafx.web; }
Klasa Animation_Sprite_ImageView
package p2_sprite_animations; import javafx.animation.AnimationTimer; import javafx.application.Application; import javafx.application.Platform; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.image.PixelReader; import javafx.scene.image.WritableImage; import javafx.stage.Stage; import utils.AnimUtil; public class Animation_Sprite_ImageView extends Application { private ImageView iv; private Image image; private WritableImage im; private PixelReader pr; private long[] durs; private final int w = 98; private final int h = 137; @Override public void init() { Image image = new Image("m2serialanimations/src/resources/bieg2.png"); durs = AnimUtil.fill4(180, 8); pr = image.getPixelReader(); } @Override public void start(Stage stage) { try { Group root = new Group(); iv = new ImageView(); root.getChildren().add(iv); Scene scene = new Scene(root, w, h); stage.setScene(scene); stage.setTitle("Sprite Animation"); stage.setOnCloseRequest(e -> Platform.exit()); stage.show(); AnimationTimer timer = new SpriteTimer(); timer.start(); } catch (Exception e) { e.printStackTrace(); } } private class SpriteTimer extends AnimationTimer { long start = System.currentTimeMillis(); int counter = 0; @Override public void handle(long now) { long teraz = System.currentTimeMillis(); long elapsed = teraz - start; if (elapsed > durs[counter]) { WritableImage im = new WritableImage(pr, counter * w, 0, w, h); iv.imageProperty().set(im); counter++; if (counter > durs.length - 1) { counter = 0; start = System.currentTimeMillis(); } } } } }
Metoda AnimUtil.fill4()
public static long[] fill4(long millis, int frames){ long d = 0; long[] durs = new long[frames]; for(int i =0; i< frames; i++){ durs[i]= d; d += millis; } return durs; }
Po uruchomieniu klasy zobaczymy animację biegnącego w miejscu chłopca.