65.9K
CodeProject 正在变化。 阅读更多。
Home

JavaFX 中从图像序列创建动画

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (2投票s)

2014 年 6 月 21 日

CPOL

3分钟阅读

viewsIcon

29184

downloadIcon

927

使用图像序列创建一个简单的动画

引言

JavaFX 是一个用于创建和交付可在各种设备上运行的富互联网应用程序 (RIA) 的软件平台。JavaFX 用于创建富互联网应用程序,例如在线游戏等。 在浏览时,我看到了一组狗走路的图像。 这张图片促使我写了这个技巧。

Using the Code

我们需要一系列图像来创建动画。 使用这个技巧,我们可以创建行走、飞行、游泳等的动画。

你可以从这里获取狗走路的图像序列:http://docs.autodesk.com/3DSMAX/12/ENU/3ds%20Max%202010%20Tutorials/images/MED/Renoir-Tut/English/quadruped/dog_walk.png

使用 Gimp/Photoshop 将序列制作成单个图像。 重要的是将背景设置为透明。 否则动画效果不会很好。

现在,下一步是在 JavaFX 中创建图像对象。

final static Image DOG_1 =  new Image(JavaFX_12.class.getResource("1.png").toString());
final static Image DOG_2 =  new Image(JavaFX_12.class.getResource("2.png").toString());
final static Image DOG_3 =  new Image(JavaFX_12.class.getResource("3.png").toString());
final static Image DOG_4 =  new Image(JavaFX_12.class.getResource("4.png").toString());
final static Image DOG_5 =  new Image(JavaFX_12.class.getResource("5.png").toString());
final static Image DOG_6 =  new Image(JavaFX_12.class.getResource("6.png").toString());
final static Image DOG_7 =  new Image(JavaFX_12.class.getResource("7.png").toString());
final static Image DOG_8 =  new Image(JavaFX_12.class.getResource("8.png").toString());
final static Image DOG_9 =  new Image(JavaFX_12.class.getResource("9.png").toString());    
final static Image BG =  new Image(JavaFX_12.class.getResource("bg.jpg").toString()); 

DOG_x”是我的狗的图像对象,“JavaFX_12”是我的主类,“x.png”是我的第一张图像,而BG 是我的背景图像对象。(x - 整数)。

final ImageView dog1 = new ImageView(DOG_1);
final ImageView dog2 = new ImageView(DOG_2);
final ImageView dog3 = new ImageView(DOG_3);
final ImageView dog4 = new ImageView(DOG_4);
final ImageView dog5 = new ImageView(DOG_5);
final ImageView dog6 = new ImageView(DOG_6);
final ImageView dog7 = new ImageView(DOG_7);
final ImageView dog8 = new ImageView(DOG_8);
final ImageView dog9 = new ImageView(DOG_9);
final ImageView bg = new ImageView(BG);

上面的代码是从先前创建的图像对象创建图像视图。 因此,现在我们创建了图像的 ImageView 对象。

下一步是创建一个 Group 对象来包含“dog”的图像。

private Group dog;
dog = new Group(dog1);
dog.setTranslateX(300);
dog.setTranslateY(450);

第一个 ImageView 对象“dog1”被添加到组中,并使用成员函数“setTranslateX”和“setTranslateY”设置狗的位置。

下一步是创建行走动画。 要从图像创建动画,我们需要快速连续地显示图像。 根据图像序列的数量,我们可以设置速度。 如果图像数量很多,那么我们需要在单位时间内显示较少的图像。

TimelineBuilder.create()
        .cycleCount(Animation.INDEFINITE)
        .keyFrames(
            new KeyFrame(Duration.millis(100), new EventHandler<ActionEvent>(){
                @Override
                public void handle(ActionEvent t) {
                    dog.getChildren().setAll(dog1);
                }
            }),
            new KeyFrame(Duration.millis(200), new EventHandler<ActionEvent>(){
                @Override
                public void handle(ActionEvent t) {
                     dog.getChildren().setAll(dog2);
                }
            }),
            new KeyFrame(Duration.millis(300), new EventHandler<ActionEvent>(){
                @Override
                public void handle(ActionEvent t) {
                     dog.getChildren().setAll(dog3);
                }
            }),
            new KeyFrame(Duration.millis(400), new EventHandler<ActionEvent>(){
                @Override
                public void handle(ActionEvent t) {
                     dog.getChildren().setAll(dog4);
                }
            }),
            new KeyFrame(Duration.millis(500), new EventHandler<ActionEvent>(){
                @Override
                public void handle(ActionEvent t) {
                     dog.getChildren().setAll(dog5);
                }
            }),
            new KeyFrame(Duration.millis(600), new EventHandler<ActionEvent>(){
                @Override
                public void handle(ActionEvent t) {
                     dog.getChildren().setAll(dog6);
                }
            }),
            new KeyFrame(Duration.millis(700), new EventHandler<ActionEvent>(){
                @Override
                public void handle(ActionEvent t) {
                     dog.getChildren().setAll(dog7);
                }
            }),
            new KeyFrame(Duration.millis(800), new EventHandler<ActionEvent>(){
                @Override
                public void handle(ActionEvent t) {
                     dog.getChildren().setAll(dog8);
                }
            }),
            new KeyFrame(Duration.millis(900), new EventHandler<ActionEvent>(){
                @Override
                public void handle(ActionEvent t) {
                     dog.getChildren().setAll(dog9);
                }
            })
        )
        .build().play();

从 0 到 100 毫秒,第一张图像“1.png”将显示,接下来的 100 毫秒显示下一张图像,直到显示所有 9 张图像。 在显示最后一张图像后,图像显示过程将从第一张图像重新开始。 这是因为我们设置了动画循环为无限“cycleCount(Animation.INDEFINITE)”。

现在我们的狗有了生命,开始活动腿部了!!!但狗仍然站在那里,没有移动!!!。 为了让狗沿着 X 轴移动,产生行走的感觉。

private void startWalking() 
{
    walk = TranslateTransitionBuilder.create()
            .node(dog)
            .fromX(-200)
            .toX(800)
            .duration(Duration.seconds(5))
            .onFinished(new EventHandler<ActionEvent>()
                    {
                        @Override
                        public void handle(ActionEvent t) {
                            startWalking();   
                        }
                    }).build();
    walk.play();
}

创建了函数“startWalking()”来让狗沿着 X 轴从 -200 移动到 800。 要移动的对象是组“dog”,狗将在 5 秒内从 -200 位置移动到 8.00 位置。 当“walk”动画到达 X 轴上的 800 位置时,动画将结束。 当“walk”结束时,它将从 -200 位置重新开始。

现在我们要进行最后一步。 将这些对象 bg(背景 ImageView)dog(Group) 添加到一个名为“root”的组中。

final Group root = new Group(bg, txt, dog);        
Scene scene = new Scene(root, 800, 600);        
primaryStage.setTitle("Designer: AJITH KP");
primaryStage.setScene(scene);
primaryStage.show();
startWalking();

现在创建一个带有“root”组的 Scene 对象,并将窗口大小设置为 800x600。 要将场景加载到窗口,我们必须使用 Stage 类的“setScene()”函数。 要显示当前阶段,我们必须调用 Stage 类的“show()”函数。 最后,我们必须调用函数“startWalking()”来动画狗。

我希望你喜欢这个技巧和动画技巧。

© . All rights reserved.