JavaFX:创建Sprite动画

到目前为止,尽管我的大多数文章都涉及JavaFX属性和绑定,但今天我想写一讲我也致力于JavaFX运行时的另一部分:动画API。

在本文中,我将解释如何在JavaFX中编写自定义动画,以及如何使用这种方法为Sprite动画创建类。 (这对我在33rd Conference上的会议来说也是一种好习惯。我计划在短短一个小时内用JavaFX编写一个游戏。这将很有趣!) :-)

运动中的马


有很多非常好的文章介绍了预定义的过渡(TranslateTransition,RotateTransition等)和时间表。 在大多数情况下,这些方法是足够的,但在某些情况下,只需要更大的灵活性即可。 这就是Transition类开始起作用的时候,可以扩展该类以定义自定义动画。 要通过扩展Transition编写自己的动画类,需要两个步骤:

  1. 指定一个周期的持续时间
  2. 实现interpolate()方法

一个周期的持续时间

您可以通过调用受保护的方法setCycleDuration()来设置周期的持续时间。 在大多数情况下,持续时间是固定的(如果动画仅使用一次)或可由用户配置。 JavaFX运行时中几乎所有预定义的转换都属于第二类。 他们通过duration属性公开了周期的持续时间,您可能也想在您的课程中做到这一点。 在极少数情况下,循环的持续时间取决于其他值。 例如,SequentialTransition和ParallelTransition的持续时间取决于其子代的持续时间。
您可以随意更改循环持续时间,但是请注意,它不会影响当前正在运行的动画。 只有在动画停止并重新开始之后,才考虑新的循环持续时间。

interpolate()方法

interpolate()方法是抽象的,需要重写。 它定义了动画的实际行为。 播放动画时,运行时在每帧中调用interpolate()方法。 传入值frac,0.0到1.0之间的双精度值(包括两端值),用于指定当前位置。 值0.0标记动画的开始,值1.0标记动画的结束。 之间的任何值都定义相对位置。 请注意,计算frac的值时已经考虑了可能的内插器。

类SpriteAnimation

为了演示如何定义自定义过渡,我们将看一个允许我们制作Sprite动画的类。 它会拍摄具有几帧的图像,然后将视口随时间从一帧移到另一帧。 我们将用Eadweard Muybridge着名的“运动中的马”测试这一节课。 聊够了,这里是代码:

package sandboxfx;import javafx.animation.Interpolator;
import javafx.animation.Transition;
import javafx.geometry.Rectangle2D;
import javafx.scene.image.ImageView;
import javafx.util.Duration;public class SpriteAnimation extends Transition {private final ImageView imageView;private final int count;private final int columns;private final int offsetX;private final int offsetY;private final int width;private final int height;private int lastIndex;public SpriteAnimation(ImageView imageView, Duration duration, int count,   int columns,int offsetX, int offsetY,int width,   int height) {this.imageView = imageView;this.count     = count;this.columns   = columns;this.offsetX   = offsetX;this.offsetY   = offsetY;this.width     = width;this.height    = height;setCycleDuration(duration);setInterpolator(Interpolator.LINEAR);}protected void interpolate(double k) {final int index = Math.min((int) Math.floor(k * count), count - 1);if (index != lastIndex) {final int x = (index % columns) * width  + offsetX;final int y = (index / columns) * height + offsetY;imageView.setViewport(new Rectangle2D(x, y, width, height));lastIndex = index;}}
}
清单1:SpriteAnimation类

为了简单起见,此示例类仅接受构造函数中的所有参数,不允许以后更改它们。 在大多数情况下,这就足够了。
该类需要一个ImageView,一个周期的持续时间(即遍历所有帧应花费的时间),帧数,列数(图像中的一行中有多少帧),第一帧的偏移量以及所有帧的宽度和高度。 通过调用setCycleDuration()将整个周期的持续时间传递给超类,并存储所有其他值。 作为构造函数的最后一步,将内插器设置为线性。 默认情况下,为所有过渡设置缓动插值器,因为通常这会产生最佳效果。 但是在我们的例子中,我们希望以相同的速度遍历所有帧,并且缓和插值器看起来很奇怪。 interpolate()方法采用传入的值并计算当前需要显示的帧。 如果自上次调用interpolate()以来它发生了变化,则将计算新帧的位置,并相应地设置ImageView的视口。 而已。

运动中的马

为了演示SpriteAnimation类,我们将对“运动中的马”进行动画处理。 做到这一点的代码很简单,大部分工作已经完成。 它创建一个将视口设置为第一帧的ImageView,并实例化SpriteAnimation类。 参数仅是估计值,您可能需要对其进行一些调整。

package sandboxfx;import javafx.animation.Animation;
import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;
import javafx.util.Duration;public class SandboxFX extends Application {private static final Image IMAGE = new Image("http://upload.wikimedia.org/wikipedia/commons/7/73/The_Horse_in_Motion.jpg");private static final int COLUMNS  =   4;private static final int COUNT    =  10;private static final int OFFSET_X =  18;private static final int OFFSET_Y =  25;private static final int WIDTH    = 374;private static final int HEIGHT   = 243;public static void main(String[] args) {launch(args);}public void start(Stage primaryStage) {primaryStage.setTitle("The Horse in Motion");final ImageView imageView = new ImageView(IMAGE);imageView.setViewport(new Rectangle2D(OFFSET_X, OFFSET_Y, WIDTH, HEIGHT));final Animation animation = new SpriteAnimation(imageView,Duration.millis(1000),COUNT, COLUMNS,OFFSET_X, OFFSET_Y,WIDTH, HEIGHT);animation.setCycleCount(Animation.INDEFINITE);animation.play();primaryStage.setScene(new Scene(new Group(imageView)));primaryStage.show();}
}
清单2:JavaFX中的动静

结论

通过扩展Transition类来定义自己的动画非常简单。 但是,这是一种非常强大的方法,因为以这种方式创建的动画具有常规动画所具有的所有功能。 例如,您可以通过更改速率来越来越慢地播放它,甚至可以向后播放它。 您可以循环运行它,也可以在ParallelTransition和SequentialTransition中使用它来创建更复杂的动画。

参考: JCG合作伙伴 Michael Heinrichs 使用JavaFX创建Sprite动画   在Mike的Blog上 。


翻译自: https://www.javacodegeeks.com/2012/03/javafx-creating-sprite-animation.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373404.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java tick_Java中的Clock tick()方法

可以使用tick()Java中Clock类中的方法在所需的时间范围内舍入基本时钟的瞬间。此方法需要两个参数,即基本时钟和滴答的持续时间。同样,返回在所需持续时间内四舍五入的基本时钟时刻。演示此的程序如下所示-示例import java.time.*;public class Main {pu…

JAVA 常用框架和工具

集成开发工具(IDE):Eclipse、MyEclipse、Spring Tool Suite(STS)、Intellij IDEA、NetBeans、JBuilder、JCreator JAVA服务器:tomcat、jboss、websphere、weblogic、resin、jetty、apusic、apache 负载均衡…

MySQL Doublewrite Buffer及业务评估

1. 关于Doublewrite Buffe的总结 Doublewrite Buffer:Doublewrite Buffer出现的初衷是防止buffer pool中的脏页刷新到磁盘中,出现部分写的问题,innodb页大小一般为16k,而Linux操作系统的block size一般为4k。这样在刷新的过程中&a…

使用UIBinder的GWT自定义按钮

这是一个有关如何在GWT上使用UIBinder创建自定义按钮的示例。 public class GwtUIBinderButton implements EntryPoint {public void onModuleLoad() {Button button new Button();button.setText("Button");button.addClickHandler(new ClickHandler(){Overridepub…

delete postman 传参_PostMan 传参boolean 类型,接口接受的值一直是false

情形:最近写前台页面的一个按钮,功能是:点击后切换状态,显示是或否。字段名称是isTest,类型是boolean 。写完接口,拿postMan测试,传参如下:但是后台接口接受的数据 一直是false,处理&#xff1a…

前端学PHP之文件操作

前端学PHP之文件操作 前面的话 在程序运行时,程序本身和数据一般都存在内存中,当程序运行结束后,存放在内存中的数据被释放。如果需要长期保存程序运行所需的原始数据,或程序运行产生的结果,就需要把数据存储在文件或数…

腾讯云CentOS6.5下安装mysql,并配置好远程访问等权限,途中遇到的问题

1.使用yum命令安装mysql [rootbogon ~]# yum -y install mysql-server 2.设置开机启动 [rootbogon ~]# chkconfig mysqld on 3.启动MySQL服务 [rootbogon ~]# service mysqld start 4.设置MySQL的root用户设置密码 [rootbogon ~]# mysql -u root mysql> select u…

休眠性能提示:脏收集效果

在使用Hibernate作为ORM开发服务器和嵌入式应用程序8年后,我全力以赴地寻求提高Hibernate性能的解决方案,阅读博客和参加会议,我决定与您分享这几年获得的知识。 这是更多新帖子中的第一篇: 去年,我以Devoxx的身份参加…

java runtime 异常_Java中RuntimeException和Exception

在java的异常类体系中,Error和RuntimeException是非检查型异常,其他的都是检查型异常。所有方法都可以在不声明throws的情况下抛出RuntimeException及其子类不可以在不声明的情况下抛出非RuntimeException简单的说,非RuntimeException必要自己写catch块处…

BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]

3130: [Sdoi2013]费用流 Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 960 Solved: 505[Submit][Status][Discuss]Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识。 最大流问题:给定一张有向图表示运输网络…

Linux Shell 003-变量

Linux Shell 003-变量 本节关键字:Linux、Shell、变量、全局变量、系统变量 相关指令:read、echo、unset、export 变量的含义 变量是用来临时保存数据的,该数据是可以变化的数据。如果某个内容需要多次使用,并且在代码中重复出现…

Java自动机实现

这篇文章将解决在Java中实现有限状态机的问题。 如果您不知道什么是FSM或在什么地方可以使用FSM,您可能会热衷于阅读此 , 这个和这个 。 如果您发现自己在设计上使用FSM的情况,则可能已经开始为实现相同接口的每个状态编写类。 一个好的设计可…

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files这个文件找不到

在C:\Windows\Microsoft.NET\Framework64\v4.0.30319文件夹下面建立Temporary ASP.NET Files 文件夹(Framework64 注意64,这个可能是我们用的64位系统,但是vs2010不分32位还是64位,所以在C:\Windows\Microsoft.NET\Framework\v4.0…

java电脑运行视频演示_javaweb视频第一天(二)

无论通过哪种方式得到的class类对象,是同一个。比较的是地址码这里教会你:如何去使用class对象现在就知道这个:如何使用反射,并且说反射是实现了什么样的功能。如何通过反射得到里面的相应字段,得到里面的相应函数等等…

模型驱动 ModelDriven

ModelDriven:模型驱动,对所有action的模型对象进行批处理. 我们在开发中, 在action中一般是用实体对象,然后给实体对象get,set方法。 RegAction{   User user ;   //get/set} 然后在jsp页面中给action中的user属性绑定值是通过如下方式 &…

本月风味– Neo4j和Heroku

Neo4j今年早些时候发起了一项挑战,即“ 种子播云 ”,以使人们使用Neo4j附加组件在Heroku上创建模板或演示应用程序。 经过许多内部辩论之后,我决定进入,但由于缺乏想法而陷入绝望。 当我什么都没做的时候,这个主意就出…

1 + 11 + 1111+ 11111+ ..... + 11111(2016个) 结果是几位数

# -*- coding: utf-8 -*- """ Created on Mon Mar 21 20:38:06 2016author: yanjie """1 11 1111 11111 ..... 11111(2016个) 结果是几位数 用什么数据结构 有几个6 写算法a []; m 0; six 0; for i in range(2016,0,-1):b (im) % 10;m (…

[回归分析][10]--相关误差的问题

[回归分析][10]--相关误差的问题这一篇文章还是来分析相关误差的问题。 1.游程数 定义:游程数--残差穿过x-轴的次数 用这个可以检查如残差有一块在x轴上面,一块在x轴下面的情形。 如上面这样的残差 下面构造两个统计量: 其中 n…

Spring 3 MVC异常处理程序

我遇到的大多数Spring 3错误处理示例代码似乎都提供了其用法的最简单概述,但是,有人说,如何处理错误比正常代码的工作方式更为重要。 前一天,当我在Spring(2)错误处理程序中遇到一个简单的GOTCHA时&#xf…

java编译找不到符号_javac编译时找不到符号?

我是个新手,在linux使用java编程时,出现这个情况。我把要引的包放在classpath中,红色部分:export CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$HADOOP_HOME/hadoop-1.0.4.core.jar:${CLASSPATH}通过echo $CLASSP…