JavaFX:创建Sprite动画
在本文中,我將解釋如何在JavaFX中編寫自定義動(dòng)畫,以及如何使用這種方法為Sprite動(dòng)畫創(chuàng)建類。 (這對(duì)我在33rd Conference上的會(huì)議來(lái)說(shuō)也是一種好習(xí)慣。我計(jì)劃在短短一個(gè)小時(shí)內(nèi)用JavaFX編寫一個(gè)游戲。這將很有趣!)
| 運(yùn)動(dòng)中的馬 | 
 有很多非常好的文章介紹了預(yù)定義的過(guò)渡(TranslateTransition,RotateTransition等)和時(shí)間表。 在大多數(shù)情況下,這些方法是足夠的,但在某些情況下,只需要更大的靈活性即可。 這就是Transition類開(kāi)始起作用的時(shí)候,可以擴(kuò)展該類以定義自定義動(dòng)畫。 要通過(guò)擴(kuò)展Transition編寫自己的動(dòng)畫類,需要兩個(gè)步驟: 
一個(gè)周期的持續(xù)時(shí)間
 您可以通過(guò)調(diào)用受保護(hù)的方法setCycleDuration()來(lái)設(shè)置周期的持續(xù)時(shí)間。 在大多數(shù)情況下,持續(xù)時(shí)間是固定的(如果動(dòng)畫僅使用一次)或可由用戶配置。 JavaFX運(yùn)行時(shí)中幾乎所有預(yù)定義的轉(zhuǎn)換都屬于第二類。 他們通過(guò)duration屬性公開(kāi)了周期的持續(xù)時(shí)間,您可能也想在您的課程中做到這一點(diǎn)。 在極少數(shù)情況下,循環(huán)的持續(xù)時(shí)間取決于其他值。 例如,SequentialTransition和ParallelTransition的持續(xù)時(shí)間取決于其子代的持續(xù)時(shí)間。 
 您可以隨意更改循環(huán)持續(xù)時(shí)間,但是請(qǐng)注意,它不會(huì)影響當(dāng)前正在運(yùn)行的動(dòng)畫。 只有在動(dòng)畫停止并重新開(kāi)始之后,才考慮新的循環(huán)持續(xù)時(shí)間。 
interpolate()方法
interpolate()方法是抽象的,需要重寫。 它定義了動(dòng)畫的實(shí)際行為。 播放動(dòng)畫時(shí),運(yùn)行時(shí)在每幀中調(diào)用interpolate()方法。 傳入值frac,0.0到1.0之間的雙精度值(包括兩端值),用于指定當(dāng)前位置。 值0.0標(biāo)記動(dòng)畫的開(kāi)始,值1.0標(biāo)記動(dòng)畫的結(jié)束。 之間的任何值都定義相對(duì)位置。 請(qǐng)注意,計(jì)算frac的值時(shí)已經(jīng)考慮了可能的內(nèi)插器。
類SpriteAnimation
為了演示如何定義自定義過(guò)渡,我們將看一個(gè)允許我們制作Sprite動(dòng)畫的類。 它會(huì)拍攝具有幾幀的圖像,然后將視口隨時(shí)間從一幀移到另一幀。 我們將用Eadweard Muybridge著名的“運(yùn)動(dòng)中的馬”測(cè)試這一節(jié)課。 聊夠了,這里是代碼:
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類 為了簡(jiǎn)單起見(jiàn),此示例類僅接受構(gòu)造函數(shù)中的所有參數(shù),不允許以后更改它們。 在大多數(shù)情況下,這就足夠了。 
 該類需要一個(gè)ImageView,一個(gè)周期的持續(xù)時(shí)間(即遍歷所有幀應(yīng)花費(fèi)的時(shí)間),幀數(shù),列數(shù)(圖像中的一行中有多少幀),第一幀的偏移量以及所有幀的寬度和高度。 通過(guò)調(diào)用setCycleDuration()將整個(gè)周期的持續(xù)時(shí)間傳遞給超類,并存儲(chǔ)所有其他值。 作為構(gòu)造函數(shù)的最后一步,將內(nèi)插器設(shè)置為線性。 默認(rèn)情況下,為所有過(guò)渡設(shè)置緩動(dòng)插值器,因?yàn)橥ǔ_@會(huì)產(chǎn)生最佳效果。 但是在我們的例子中,我們希望以相同的速度遍歷所有幀,并且緩和插值器看起來(lái)很奇怪。 interpolate()方法采用傳入的值并計(jì)算當(dāng)前需要顯示的幀。 如果自上次調(diào)用interpolate()以來(lái)它發(fā)生了變化,則將計(jì)算新幀的位置,并相應(yīng)地設(shè)置ImageView的視口。 而已。 
運(yùn)動(dòng)中的馬
為了演示SpriteAnimation類,我們將對(duì)“運(yùn)動(dòng)中的馬”進(jìn)行動(dòng)畫處理。 做到這一點(diǎn)的代碼很簡(jiǎn)單,大部分工作已經(jīng)完成。 它創(chuàng)建一個(gè)將視口設(shè)置為第一幀的ImageView,并實(shí)例化SpriteAnimation類。 參數(shù)僅是估計(jì)值,您可能需要對(duì)其進(jìn)行一些調(diào)整。
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中的動(dòng)靜結(jié)論
通過(guò)擴(kuò)展Transition類來(lái)定義自己的動(dòng)畫非常簡(jiǎn)單。 但是,這是一種非常強(qiáng)大的方法,因?yàn)橐赃@種方式創(chuàng)建的動(dòng)畫具有常規(guī)動(dòng)畫所具有的所有功能。 例如,您可以通過(guò)更改速率來(lái)越來(lái)越慢地播放它,甚至可以向后播放它。 您可以循環(huán)運(yùn)行它,也可以在ParallelTransition和SequentialTransition中使用它來(lái)創(chuàng)建更復(fù)雜的動(dòng)畫。
參考: JCG合作伙伴 Michael Heinrichs 使用JavaFX創(chuàng)建Sprite動(dòng)畫 ? 在Mike的Blog上 。
翻譯自: https://www.javacodegeeks.com/2012/03/javafx-creating-sprite-animation.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的JavaFX:创建Sprite动画的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: Oracle通过邀请Weaver和Chi
- 下一篇: 软件锁怎么更改密码
