#眉標= JavaFX 1.2、NetBeans、Timeline #副標=從實例學習JavaFX(3) #大標=JavaFX的GUI與動畫開發 #作者=文╱圖 陳廷嘉 ============= 程式1 var state = "init"; var bgColor = Color.GRAY; //…(1) var stageWidth = 240; var stageHeight = 320; //…(2) Stage { title: "JavaFX Fighers Game" width: stageWidth height: stageHeight scene: Scene {  fill: bind bgColor, //…(3)  content: [ Text {   x: 40; y: 140   content: "遊戲開始囉!!"   fill: Color.WHITE;   font: Font{ size: 24 }   visible: bind (state == "start") //…(4) }, Button {   text: "Start"   translateX: 180   translateY: 260   visible: bind (state == "init") //…(4)   action: function() { //…(5) state = "start"; bgColor = Color.web("#0043AB"); //…(1) } } ] } } ================ ============= 程式2 class Bounce extends ImageView { //…(1) public-init var stageWidth:Number; public-init var stageHeight:Number; //…(2) protected var timelineX:Timeline; protected var timelineY:Timeline; init { image = Image { url: "{__DIR__}media/brownplane.png" }//…(3) var boundaryX = stageWidth - image.width; var boundaryY = stageHeight - image.height - 35; //…(4) // … 未完 } } ================ ============= 程式3 init { // 接續前面 timelineX = Timeline { repeatCount: Timeline.INDEFINITE autoReverse: true //…(1) keyFrames: [ //…(2) at (0s) { translateX => 0.0 }, at (2s) { translateX => boundaryX tween Interpolator.LINEAR } ] }; timelineY = Timeline { repeatCount: Timeline.INDEFINITE autoReverse: true keyFrames: [ //…(2) at (0s) { translateY => 0.0 }, at (4s) { translateY => boundaryY tween Interpolator.LINEAR }, ] }; } package function start() : Void { //…(3) timelineX.playFromStart(); timelineY.playFromStart(); } ================ ============= 程式4 public class Island extends ImageView { //…(1) public-init var imageUrl:String; //…(2) protected var timeline:Timeline; init { this.image = Image {url: imageUrl} this.visible = false; //…(3) var stratX = Main.WIDTH * Math.random(); var startY = -image.height; //…(4) // … 未完 } } ================ ============= 程式5 init { // 接續前面 timeline = Timeline { keyFrames: [ at (0s) { //…(1) translateX => stratX; translateY => startY; visible => true }, at (16s) { //…(2) translateY => Main.HEIGHT tween Interpolator.LINEAR } ] }; } package function start() : Void { //…(3) timeline.playFromStart(); this.toBack(); } ================ ============= 程式6 public class Level extends Scene { //…(1) public-init var timeBetweenIslands = 2s; //…(2) protected var islandUrls = ["bigisland.png", "smallisland.png", "volcanoisland.png"];//…(3) var bounce = Bounce { speed: 50 }; var random = new Random(); var lastMoveTime:Long = System.currentTimeMillis(); //…(4) init { fill = Color.web("#0043AB"); cursor = Cursor.NONE; //…(5) // … 未完 } } ================ ============= 程式7 init { // 接續前面 content = [ Rectangle { //…(1) opacity: 0; width: Main.WIDTH; height: Main.HEIGHT; onMouseMoved : function(evt:MouseEvent) { //…(2) def t:Long = System.currentTimeMillis(); if((t - lastMoveTime) > 50) { bounce.move(evt.x, evt.y); lastMoveTime = t; } }; } ]; Timeline { //…(3) repeatCount: Timeline.INDEFINITE keyFrames: [ KeyFrame { time: timeBetweenIslands action: newIsland } ] }.playFromStart(); insert bounce into content; //…(4) bounce.start(); } function newIsland() : Void { //…(5) var islandUrl = islandUrls[ random.nextInt(sizeof islandUrls)]; var island = Island { imageUrl: "{__DIR__}media/{islandUrl}" }; insert island into content; island.start(); } ================ ============= 程式8 package def WIDTH = 360; package def HEIGHT = 480; //…(1) var scene : Scene = new MainMenu(); //…(2) package var state = "init" on replace { if (state.equals("init")) scene = new MainMenu(); if (state.equals("start")) scene = new Level(); }; var stage = Stage { title: "JavaFX Fighers Game" width: WIDTH height: HEIGHT scene: bind scene //…(3) } function run() { //…(4) stage.visible = true; } ================ ============= 程式9 public class Cloud extends CustomNode { //…(1) protected var timeline:Timeline; override function create() : Node { this.visible = false; opacity = Math.random(); if (opacity < 0.6) opacity = 0.6; //…(2) var node = Path { //…(3) stroke : Color.DODGERBLUE; fill : LinearGradient { startX:60, startY:10, endX:10 endY:80 , proportional: false stops: [ Stop { offset: 0.0 color: Color.DODGERBLUE}, // 省略.. ] }; elements : [ MoveTo {x: 15 y: 15 }, ArcTo {x: 50 y: 10 radiusX: 20 radiusY: 20 sweepFlag: true}, // 省略.. ]; } var stratX = Main.WIDTH * Math.random(); var startY = -64; //…(4) timeline = Timeline { //…(5) keyFrames: [ // 省略.. ] }; return node; } // 省略.. } ================ ============= 程式10 public class Weapon extends CustomNode { //…(1) var imageUrl:String = "{__DIR__}media/bullets.png"; override function create() : Node { this.visible = false; var node = ImageView { image: Image {url: imageUrl} }; timeline = Timeline { keyFrames: [ at (0s) { visible => true }, at (2s) { //…(2) translateY => -node.image.height tween Interpolator.LINEAR } ] }; return node; } //省略.. } ================ ============= 程式11 init { // 省略.. content = [ Rectangle { // 省略.. onMouseClicked : //…(1) function(evt:MouseEvent) { def t:Long = System.currentTimeMillis(); if((t - lastShootTime) > 200) { var weapon = Weapon { //…(2) translateX : evt.x + 25, translateY : evt.y - 5 } addGameObject(weapon); //…(3) lastShootTime = t; } }; } ]; // 省略.. } ================ ============= 參考資料 ●Flash Game Development with Flex and Actionscript:http://www.brighthub.com/internet/web-development/articles/11012.aspx。 ●Build GUI Applications With JavaFX:http://jscpreview.sfbay.sun.com/javafx/1/tutorials/ui/。 ================