mirror of
https://gitlab.com/cc-ru/ocelot/ocelot-desktop.git
synced 2025-12-20 02:59:19 +01:00
80 lines
2.6 KiB
Scala
80 lines
2.6 KiB
Scala
package ocelot.desktop.node
|
|
|
|
import ocelot.desktop.color.RGBAColorNorm
|
|
import ocelot.desktop.geometry.{Size2D, Vector2D}
|
|
import ocelot.desktop.graphics.{Graphics, IconSource}
|
|
import ocelot.desktop.node.SmokeParticleNode._
|
|
import ocelot.desktop.ui.UiHandler
|
|
import ocelot.desktop.ui.particle.Particle
|
|
import ocelot.desktop.util.Spritesheet
|
|
|
|
import scala.util.Random
|
|
|
|
trait SmokeParticleNode extends Node {
|
|
protected def emitSmoke(): Unit = synchronized {
|
|
for (_ <- 1 to randomCount) {
|
|
UiHandler.root.workspaceView.particleSystem.add(new SmokeParticle)
|
|
}
|
|
}
|
|
|
|
private class SmokeParticle extends Particle(ttl = randomDuration) {
|
|
private val color: RGBAColorNorm = randomColor
|
|
private var velocity: Vector2D = Vector2D(randomVelocityComponent, randomVelocityComponent)
|
|
private var offset: Vector2D = Vector2D(0, 0)
|
|
|
|
override def update(dt: Float): Unit = {
|
|
time += dt
|
|
offset += (velocity + SmokeParticleVolatilizationSpeed) * dt * speed
|
|
velocity *= math.pow(SmokeParticleVelocityDamping, dt).toFloat
|
|
}
|
|
|
|
override def draw(g: Graphics): Unit = {
|
|
val spriteRect = Spritesheet.sprites(IconSource.Particles.Smoke.path)
|
|
|
|
val animationFrameCount = spriteRect.h / spriteRect.w
|
|
val animationFrame = (time / ttl * animationFrameCount).toInt
|
|
|
|
val particlePosition = bounds.center + offset - SmokeParticleSize.toVector * .5f
|
|
|
|
g.sprite(
|
|
IconSource.Particles.Smoke.path,
|
|
particlePosition.x,
|
|
particlePosition.y,
|
|
SmokeParticleSize.width,
|
|
SmokeParticleSize.height,
|
|
color,
|
|
Some(spriteRect.copy(
|
|
y = spriteRect.y + animationFrame * spriteRect.w,
|
|
h = spriteRect.w,
|
|
)),
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
private object SmokeParticleNode {
|
|
private final val SmokeParticleSize: Size2D = Size2D(32, 32)
|
|
private final val SmokeParticleVelocityRange: Float = 300
|
|
private final val SmokeParticleVolatilizationSpeed: Vector2D = Vector2D(0, -50)
|
|
private final val SmokeParticleVelocityDamping: Float = .1f
|
|
private final val SmokeParticleCount: (Int, Int) = (10, 20)
|
|
private final val SmokeParticleAnimationDuration: (Float, Float) = (1f, 4f)
|
|
|
|
private def randomVelocityComponent: Float = Random.between(
|
|
-SmokeParticleVelocityRange,
|
|
SmokeParticleVelocityRange,
|
|
)
|
|
private def randomColor: RGBAColorNorm = {
|
|
val channel = Random.between(.5f, .9f)
|
|
RGBAColorNorm(channel, channel, channel)
|
|
}
|
|
private def randomDuration: Float = Random.between(
|
|
SmokeParticleAnimationDuration._1,
|
|
SmokeParticleAnimationDuration._2,
|
|
)
|
|
private def randomCount: Int = Random.between(
|
|
SmokeParticleCount._1,
|
|
SmokeParticleCount._2,
|
|
)
|
|
}
|