随机飘动的泡泡
import javafx.geometry.Pos import javafx.scene.canvas.Canvas import javafx.scene.canvas.GraphicsContext import javafx.scene.paint.Color import javafx.scene.paint.Paint import javafx.scene.shape.Circle import javafx.scene.text.FontWeight import tornadofx.* import java.util.* import kotlin.system.exitProcess class AlgoApp : App(AlgoFrame::class, Styles::class) { override fun stop() { super.stop() // 退出进程,runAsync也一并退出 exitProcess(0) } } class AlgoFrame : View("随机飘动的泡泡") { lateinit var cv: Canvas val R = 50.0 var circles = mutableListOf<MyCircle>() override val root = borderpane { center = canvas(700.0, 300.0) { cv = this with(cv.graphicsContext2D) { strokeRect(0.0,0.0,cv.width,cv.height) } } } private fun runn(){ runAsync { while (true) { render() AlgoVisHelper.pause(20) circles.forEach { it.move(0,0,cv.width.toInt(),cv.height.toInt()) } } } } private fun render() { repaint() } private fun repaint() { cv.graphicsContext2D.clearRect(0.0, 0.0, cv.width, cv.height) cv.graphicsContext2D.strokeRect(0.0,0.0,cv.width,cv.height) paintComponent(cv.graphicsContext2D) } private fun paintComponent(g: GraphicsContext) { g.fill = Color.RED g.stroke= Paint.valueOf("red") circles.forEach { g.strokeOval(it.centerX, it.centerY, it.radius, it.radius) } } init { circles = genCircles() paintComponent(cv.graphicsContext2D) runn() } private fun genCircles(): MutableList<MyCircle> { return (0..10).map { val x = Random().nextDouble() * (700 - 2 * R) + R val y = Random().nextDouble() * (300 - 2 * R) + R val vx = Random().nextDouble() * 11 - 5 val vy = Random().nextDouble() * 11 - 5 MyCircle(x, y, R, vx, vy) }.toMutableList() } } class MyCircle(var x: Double, var y: Double, var r: Double, var vx: Double, var vy: Double) : Circle(x, y, r) { fun move(minx: Int, miny: Int, maxx: Int, maxy: Int) { this.centerX += vx this.centerY += vy this.x += vx this.y += vy checkCollision(minx,miny,maxx,maxy) } private fun checkCollision(minx: Int, miny: Int, maxx: Int, maxy: Int) { if (x - r < minx) { x = r vx = -vx } if (x + r >= maxx) { x = maxx - r vx = -vx } if (y - r < miny) { y = r vy = -vy } if (y + r >= maxy) { y = maxy - r vy = -vy } } } class Styles : Stylesheet() { init { button { padding = box(10.px) alignment = Pos.CENTER backgroundColor += c("#DD7549") fontWeight = FontWeight.EXTRA_BOLD fontSize = 14.px and(hover) { backgroundColor += c("#A05434") textFill = Color.WHITE } } label { fontSize = 14.px textFill = Color.RED } } }