1. 程式人生 > >tornadofx動畫演示分錢問題,多種方法

tornadofx動畫演示分錢問題,多種方法

import javafx.animation.AnimationTimer
import javafx.collections.FXCollections
import javafx.scene.paint.Color
import javafx.scene.shape.Rectangle
import javafx.util.Duration
import tornadofx.*

class LearnApp : App(LearnV::class)
class LearnV : View("learn 分錢問題") {
    //    每個矩形寬度
    val w = 10.0
    //    100個矩形容器
    val rec = FXCollections.observableArrayList<Rectangle>()
    val b = (0..99)
    val money0 = 50
    //    100個人,每人money0元
    val money = b.map { money0 }.toIntArray()
    //    動畫計時器
    val aniTimer = AniTimer(this)
    //    每次給其他人10元
    val money1 = 5
    val result = stringProperty()
    val max = stringProperty()
    val h= doubleProperty()
    override val root = borderpane {
        top = vbox(5) {
            label(result) {
                isWrapText = true
            }
            label(max)
            hbox(5) {
                button("run").action {
                    //                ani()
                    aniTimer.start()
                }
                button("stop").action {
                    //                ani()
                    aniTimer.stop()
                }
                button("transform").action {
                    //                ani()
                    rec[1].transform(
                        Duration.seconds(1.0),
                        javafx.geometry.Point2D(1.0, 1.0),
                        0,
                        javafx.geometry.Point2D(1.0, 2.0),
                        100
                    )
                    rec[2].translateY = 20.0
                    rec[3].translateX = 5.0
                    rec[4].translateZ = 20.0
                    rec[5].height = 60.0
                }
            }
        }
        center = group {
            canvas {
                this.graphicsContext2D.fill=Color.AZURE
                this.height = 800.0
                this.width = 1000.0
                h.bind(heightProperty())
                for (i in money.indices) {
                    val r = rectangle(w * i, 200.0, w - 5, money0) {
                        fill = Color.BLUE
                    }
                    rec.add(r)
                }
            }
        }
//        barchart("Unit Sales Q2 2016", CategoryAxis(), NumberAxis()) {
//            series("Product X") {
//                (0..50).forEach {
//                    data("${it}", 10245)
//                }
//            }
//        }

//        prefWidth = 800.0
//        prefHeight = 800.0
    }

    fun paint() {
        var i = 0
        timeline {
            keyframe(Duration.seconds(0.10)) {
                money.forEach {
                    val j = b.random()
                    //        保證每人手裡有錢
                    if (money[i] > 0) {
                        money[i] -= money1
                        money[j] += money1
                        keyvalue(rec[i].heightProperty(), money[i])
                        keyvalue(rec[j].heightProperty(), money[j])
                    }
                    i++
                }
//                如要看排序後的結果,取消下面註釋
                money.sort()
                result.value = money.toList().toString()
                max.value = "最大值:${money.max()}"
//                println(money.toList())
            }
        }
    }

//    抖動明顯
    fun paint1() {
        var i = 0
        timeline {
            keyframe(Duration.seconds(0.10)) {
                money.forEach {
                    val j = b.random()
                    money[i] -= money1
                    money[j] += money1
                    if (money[i] > 0) {
                        rec[i].y = 500.0 - money[i]
                        keyvalue(rec[i].heightProperty(), money[i])
                    } else {
                        rec[i].fill = Color.RED
                        rec[i].y = 500.0
                        keyvalue(rec[i].heightProperty(), -money[i])
                    }
                    i++
                }
//                如要看排序後的結果,取消下面註釋
                money.sort()
                result.value = money.toList().toString()
                max.value = "最大值:${money.max()}"
//                println(money.toList())
            }
        }
    }

    fun paint2() {
        var i = 0
        money.forEach {
            val j = b.random()
            money[i] -= money1
            money[j] += money1
            if (money[i] > 0) {
//                rec[i].y = h.value/2 - money[i]
                rec[i].translateY = h.value/2 - money[i]
                rec[i].height = money[i].toDouble()
            } else {
                rec[i].fill = Color.RED
//                rec[i].y = h.value/2
                rec[i].translateY = h.value/2
                rec[i].height = -money[i].toDouble()
            }
            i++
        }
//                如要看排序後的結果,取消下面註釋
        money.sort()
        result.value = money.toList().toString()
        max.value = "最大值:${money.max()}"
//                println(money.toList())
    }

    // 此方法可以停止動畫
    class AniTimer(val learnV: LearnV) : AnimationTimer() {
        var lastTime = 0L
        override fun handle(now: Long) {
            if ((now - lastTime) > 10000000) {
                lastTime = now
            } else {
                return
            }
//            learnV.paint()
//            learnV.paint1()
            learnV.paint2()
        }
    }

    // 此方法無法停止動畫
    fun ani() {
        class AniTimer : AnimationTimer() {
            var lastTime = 0L
            override fun handle(now: Long) {
                if ((now - lastTime) > 10000000) {
                    lastTime = now
                } else {
                    return
                }
                paint()
            }
        }
        AniTimer().start()
    }

}