Skip to content

Commit bde832e

Browse files
committed
feat: add reactor trail effect to rocket landing sample
1 parent 53f339b commit bde832e

File tree

5 files changed

+91
-3
lines changed

5 files changed

+91
-3
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ dist/
1717
version.sbt
1818

1919
externals/
20+
submodules/three.js/
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package dev.cheleb.scalajswebgl.samples.three.games
2+
3+
import THREE.*
4+
import scala.scalajs.js
5+
import scala.util.Random
6+
import scala.math.*
7+
8+
class ReactorTrail(scene: Scene) {
9+
private val particles = js.Array[Mesh]()
10+
private val velocities = js.Array[Vector3]()
11+
private val lives = js.Array[Double]()
12+
13+
private val geometry = SphereGeometry(0.1, 8, 8)
14+
15+
def emit(position: Vector3, rotationZ: Double): Unit = {
16+
// Offset position to be at the bottom of the rocket
17+
val offset = Vector3(
18+
sin(rotationZ) * 0.75,
19+
-cos(rotationZ) * 0.75,
20+
0
21+
)
22+
val emitPos = position.jsClone().add(offset)
23+
24+
val color = if (Random.nextBoolean()) 0xffff00 else 0xff8800 // Yellow or Orange
25+
val material = MeshBasicMaterial(color = color)
26+
val particle = Mesh(geometry, material)
27+
28+
particle.position.copy(emitPos)
29+
30+
// Velocity is mostly opposite to thrust direction with some spread
31+
val vMag = 0.1 + Random.nextDouble() * 0.1
32+
val spread = (Random.nextDouble() - 0.5) * 0.15
33+
val velocity = Vector3(
34+
sin(rotationZ) * vMag + cos(rotationZ) * spread,
35+
-cos(rotationZ) * vMag + sin(rotationZ) * spread,
36+
(Random.nextDouble() - 0.5) * 0.05
37+
)
38+
39+
particles.push(particle)
40+
velocities.push(velocity)
41+
lives.push(1.0)
42+
scene.add(particle)
43+
}
44+
45+
def update(): Unit = {
46+
var i = 0
47+
while (i < particles.length) {
48+
val p = particles(i)
49+
val v = velocities(i)
50+
lives(i) -= 0.05
51+
52+
if (lives(i) <= 0) {
53+
scene.remove(p)
54+
p.material.foreach {
55+
case m: Material => m.dispose()
56+
case _ =>
57+
}
58+
particles.splice(i, 1)
59+
velocities.splice(i, 1)
60+
lives.splice(i, 1)
61+
} else {
62+
p.position.asInstanceOf[js.Dynamic].add(v)
63+
p.scale.asInstanceOf[js.Dynamic].multiplyScalar(0.95)
64+
i += 1
65+
}
66+
}
67+
}
68+
69+
def clear(): Unit = {
70+
particles.foreach { p =>
71+
scene.remove(p)
72+
p.material.foreach {
73+
case m: Material => m.dispose()
74+
case _ =>
75+
}
76+
}
77+
particles.length = 0
78+
velocities.length = 0
79+
lives.length = 0
80+
}
81+
}

example/client/src/main/scala/dev/cheleb/scalajswebgl/samples/three/games/RocketLandingSample.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ object RocketLandingSample {
2323
)
2424

2525
// Game Constants
26-
val GRAVITY = -0.002
27-
val THRUST = 0.01
26+
val GRAVITY = -0.0005
27+
val THRUST = 0.005
2828
val ROTATION_SPEED = 0.05
2929
val MAX_LANDING_VELOCITY = -0.10
3030

@@ -102,6 +102,7 @@ object RocketLandingSample {
102102
var landed = false
103103
var crashed = false
104104
val explosion = new ExplosionEffect(scene)
105+
val trail = new ReactorTrail(scene)
105106

106107
val keys = js.Dictionary[Boolean]()
107108
window.addEventListener("keydown", (e: dom.KeyboardEvent) => keys(e.key) = true)
@@ -119,6 +120,7 @@ object RocketLandingSample {
119120
crashed = false
120121
messageVar.set("")
121122
explosion.clear()
123+
trail.clear()
122124
rocketGroup.visible = true
123125
}
124126
reset()
@@ -137,6 +139,7 @@ object RocketLandingSample {
137139
vx += forceX
138140
vy += forceY
139141
fuel -= 0.2
142+
for (_ <- 0 until 3) trail.emit(rocketGroup.position, rotationZ)
140143
}
141144
if (keys.getOrElse("ArrowLeft", false)) {
142145
rocketGroup.rotation.z = rotationZ + ROTATION_SPEED
@@ -189,6 +192,7 @@ object RocketLandingSample {
189192
}
190193

191194
explosion.update()
195+
trail.update()
192196
renderer.render(scene, camera)
193197
}
194198

modules/three/src/main/scala/THREE/math/Vector3.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,7 @@ class Vector3(
1818
def copy(v: Vector3): this.type = js.native
1919
def add(v: Vector3): this.type = js.native
2020
def multiplyScalar(s: Double): this.type = js.native
21+
22+
@JSName("clone")
23+
def jsClone(): this.type = js.native
2124
}

submodules/three.js

Submodule three.js deleted from 1d618a2

0 commit comments

Comments
 (0)