Loading packages/EasterEgg/src/com/android/egg/landroid/Physics.kt +14 −1 Original line number Original line Diff line number Diff line Loading @@ -20,7 +20,7 @@ import android.util.ArraySet import kotlin.random.Random import kotlin.random.Random // artificially speed up or slow down the simulation // artificially speed up or slow down the simulation const val TIME_SCALE = 1f const val TIME_SCALE = 1f // simulation seconds per wall clock second // if it's been over 1 real second since our last timestep, don't simulate that elapsed time. // if it's been over 1 real second since our last timestep, don't simulate that elapsed time. // this allows the simulation to "pause" when, for example, the activity pauses // this allows the simulation to "pause" when, for example, the activity pauses Loading @@ -36,6 +36,19 @@ interface Entity { fun postUpdate(sim: Simulator, dt: Float) fun postUpdate(sim: Simulator, dt: Float) } } interface Removable { fun canBeRemoved(): Boolean } class Fuse(var lifetime: Float) : Removable { fun update(dt: Float) { lifetime -= dt } override fun canBeRemoved(): Boolean { return lifetime < 0 } } open class Body(var name: String = "Unknown") : Entity { open class Body(var name: String = "Unknown") : Entity { var pos = Vec2.Zero var pos = Vec2.Zero var opos = Vec2.Zero var opos = Vec2.Zero Loading packages/EasterEgg/src/com/android/egg/landroid/Universe.kt +25 −18 Original line number Original line Diff line number Diff line Loading @@ -43,11 +43,9 @@ const val CRAFT_SPEED_LIMIT = 5_000f const val MAIN_ENGINE_ACCEL = 1000f // thrust effect, pixels per second squared const val MAIN_ENGINE_ACCEL = 1000f // thrust effect, pixels per second squared const val LAUNCH_MECO = 2f // how long to suspend gravity when launching const val LAUNCH_MECO = 2f // how long to suspend gravity when launching const val SCALED_THRUST = true const val LANDING_REMOVAL_TIME = 3600f // one hour of simulation time interface Removable { const val SCALED_THRUST = true fun canBeRemoved(): Boolean } open class Planet( open class Planet( val orbitCenter: Vec2, val orbitCenter: Vec2, Loading Loading @@ -321,7 +319,7 @@ open class Universe(val namer: Namer, randomSeed: Long) : Simulator(randomSeed) // // (1..10).forEach { (1..10).forEach { Spark( Spark( lifetime = rng.nextFloatInRange(0.5f, 2f), ttl = rng.nextFloatInRange(0.5f, 2f), style = Spark.Style.DOT, style = Spark.Style.DOT, color = Color.White, color = Color.White, size = 1f size = 1f Loading Loading @@ -359,13 +357,22 @@ open class Universe(val namer: Namer, randomSeed: Long) : Simulator(randomSeed) entities entities .filterIsInstance<Removable>() .filterIsInstance<Removable>() .filter(predicate = Removable::canBeRemoved) .filter(predicate = Removable::canBeRemoved) .filterIsInstance<Entity>() .forEach { remove(it as Entity) } .forEach { remove(it) } constraints .filterIsInstance<Removable>() .filter(predicate = Removable::canBeRemoved) .forEach { remove(it as Constraint) } } } } } class Landing(var ship: Spacecraft?, val planet: Planet, val angle: Float, val text: String = "") : class Landing( Constraint { var ship: Spacecraft?, val planet: Planet, val angle: Float, val text: String = "", private val fuse: Fuse = Fuse(LANDING_REMOVAL_TIME) ) : Constraint, Removable by fuse { override fun solve(sim: Simulator, dt: Float) { override fun solve(sim: Simulator, dt: Float) { ship?.let { ship -> ship?.let { ship -> val landingVector = Vec2.makeWithAngleMag(angle, ship.radius + planet.radius) val landingVector = Vec2.makeWithAngleMag(angle, ship.radius + planet.radius) Loading @@ -373,17 +380,20 @@ class Landing(var ship: Spacecraft?, val planet: Planet, val angle: Float, val t ship.pos = (ship.pos * 0.5f) + (desiredPos * 0.5f) // @@@ FIXME ship.pos = (ship.pos * 0.5f) + (desiredPos * 0.5f) // @@@ FIXME ship.angle = angle ship.angle = angle } } fuse.update(dt) } } } } class Spark( class Spark( var lifetime: Float, var ttl: Float, collides: Boolean = false, collides: Boolean = false, mass: Float = 0f, mass: Float = 0f, val style: Style = Style.LINE, val style: Style = Style.LINE, val color: Color = Color.Gray, val color: Color = Color.Gray, val size: Float = 2f val size: Float = 2f, ) : Removable, Body() { val fuse: Fuse = Fuse(ttl) ) : Removable by fuse, Body(name = "Spark") { enum class Style { enum class Style { LINE, LINE, LINE_ABSOLUTE, LINE_ABSOLUTE, Loading @@ -398,10 +408,7 @@ class Spark( } } override fun update(sim: Simulator, dt: Float) { override fun update(sim: Simulator, dt: Float) { super.update(sim, dt) super.update(sim, dt) lifetime -= dt fuse.update(dt) } override fun canBeRemoved(): Boolean { return lifetime < 0 } } } } Loading Loading @@ -486,11 +493,11 @@ class Spacecraft : Body() { // exhaust // exhaust sim.add( sim.add( Spark( Spark( lifetime = sim.rng.nextFloatInRange(0.5f, 1f), ttl = sim.rng.nextFloatInRange(0.5f, 1f), collides = true, collides = true, mass = 1f, mass = 1f, style = Spark.Style.RING, style = Spark.Style.RING, size = 3f, size = 1f, color = Color(0x40FFFFFF) color = Color(0x40FFFFFF) ) ) .also { spark -> .also { spark -> Loading packages/EasterEgg/src/com/android/egg/landroid/VisibleUniverse.kt +10 −2 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,7 @@ import androidx.compose.ui.util.lerp import androidx.core.math.MathUtils.clamp import androidx.core.math.MathUtils.clamp import com.android.egg.flags.Flags.flagFlag import com.android.egg.flags.Flags.flagFlag import java.lang.Float.max import java.lang.Float.max import kotlin.math.exp import kotlin.math.sqrt import kotlin.math.sqrt const val DRAW_ORBITS = true const val DRAW_ORBITS = true Loading Loading @@ -289,7 +290,8 @@ fun ZoomedDrawScope.drawLanding(landing: Landing) { fun ZoomedDrawScope.drawSpark(spark: Spark) { fun ZoomedDrawScope.drawSpark(spark: Spark) { with(spark) { with(spark) { if (lifetime < 0) return if (fuse.lifetime < 0) return val life = 1f - fuse.lifetime / ttl when (style) { when (style) { Spark.Style.LINE -> Spark.Style.LINE -> if (opos != Vec2.Zero) drawLine(color, opos, pos, strokeWidth = size) if (opos != Vec2.Zero) drawLine(color, opos, pos, strokeWidth = size) Loading @@ -297,7 +299,13 @@ fun ZoomedDrawScope.drawSpark(spark: Spark) { if (opos != Vec2.Zero) drawLine(color, opos, pos, strokeWidth = size / zoom) if (opos != Vec2.Zero) drawLine(color, opos, pos, strokeWidth = size / zoom) Spark.Style.DOT -> drawCircle(color, size, pos) Spark.Style.DOT -> drawCircle(color, size, pos) Spark.Style.DOT_ABSOLUTE -> drawCircle(color, size, pos / zoom) Spark.Style.DOT_ABSOLUTE -> drawCircle(color, size, pos / zoom) Spark.Style.RING -> drawCircle(color, size, pos, style = Stroke(width = 1f / zoom)) Spark.Style.RING -> drawCircle( color = color.copy(alpha = color.alpha * (1f - life)), radius = exp(lerp(size, 3f * size, life)) - 1f, center = pos, style = Stroke(width = 1f / zoom) ) } } } } } } Loading Loading
packages/EasterEgg/src/com/android/egg/landroid/Physics.kt +14 −1 Original line number Original line Diff line number Diff line Loading @@ -20,7 +20,7 @@ import android.util.ArraySet import kotlin.random.Random import kotlin.random.Random // artificially speed up or slow down the simulation // artificially speed up or slow down the simulation const val TIME_SCALE = 1f const val TIME_SCALE = 1f // simulation seconds per wall clock second // if it's been over 1 real second since our last timestep, don't simulate that elapsed time. // if it's been over 1 real second since our last timestep, don't simulate that elapsed time. // this allows the simulation to "pause" when, for example, the activity pauses // this allows the simulation to "pause" when, for example, the activity pauses Loading @@ -36,6 +36,19 @@ interface Entity { fun postUpdate(sim: Simulator, dt: Float) fun postUpdate(sim: Simulator, dt: Float) } } interface Removable { fun canBeRemoved(): Boolean } class Fuse(var lifetime: Float) : Removable { fun update(dt: Float) { lifetime -= dt } override fun canBeRemoved(): Boolean { return lifetime < 0 } } open class Body(var name: String = "Unknown") : Entity { open class Body(var name: String = "Unknown") : Entity { var pos = Vec2.Zero var pos = Vec2.Zero var opos = Vec2.Zero var opos = Vec2.Zero Loading
packages/EasterEgg/src/com/android/egg/landroid/Universe.kt +25 −18 Original line number Original line Diff line number Diff line Loading @@ -43,11 +43,9 @@ const val CRAFT_SPEED_LIMIT = 5_000f const val MAIN_ENGINE_ACCEL = 1000f // thrust effect, pixels per second squared const val MAIN_ENGINE_ACCEL = 1000f // thrust effect, pixels per second squared const val LAUNCH_MECO = 2f // how long to suspend gravity when launching const val LAUNCH_MECO = 2f // how long to suspend gravity when launching const val SCALED_THRUST = true const val LANDING_REMOVAL_TIME = 3600f // one hour of simulation time interface Removable { const val SCALED_THRUST = true fun canBeRemoved(): Boolean } open class Planet( open class Planet( val orbitCenter: Vec2, val orbitCenter: Vec2, Loading Loading @@ -321,7 +319,7 @@ open class Universe(val namer: Namer, randomSeed: Long) : Simulator(randomSeed) // // (1..10).forEach { (1..10).forEach { Spark( Spark( lifetime = rng.nextFloatInRange(0.5f, 2f), ttl = rng.nextFloatInRange(0.5f, 2f), style = Spark.Style.DOT, style = Spark.Style.DOT, color = Color.White, color = Color.White, size = 1f size = 1f Loading Loading @@ -359,13 +357,22 @@ open class Universe(val namer: Namer, randomSeed: Long) : Simulator(randomSeed) entities entities .filterIsInstance<Removable>() .filterIsInstance<Removable>() .filter(predicate = Removable::canBeRemoved) .filter(predicate = Removable::canBeRemoved) .filterIsInstance<Entity>() .forEach { remove(it as Entity) } .forEach { remove(it) } constraints .filterIsInstance<Removable>() .filter(predicate = Removable::canBeRemoved) .forEach { remove(it as Constraint) } } } } } class Landing(var ship: Spacecraft?, val planet: Planet, val angle: Float, val text: String = "") : class Landing( Constraint { var ship: Spacecraft?, val planet: Planet, val angle: Float, val text: String = "", private val fuse: Fuse = Fuse(LANDING_REMOVAL_TIME) ) : Constraint, Removable by fuse { override fun solve(sim: Simulator, dt: Float) { override fun solve(sim: Simulator, dt: Float) { ship?.let { ship -> ship?.let { ship -> val landingVector = Vec2.makeWithAngleMag(angle, ship.radius + planet.radius) val landingVector = Vec2.makeWithAngleMag(angle, ship.radius + planet.radius) Loading @@ -373,17 +380,20 @@ class Landing(var ship: Spacecraft?, val planet: Planet, val angle: Float, val t ship.pos = (ship.pos * 0.5f) + (desiredPos * 0.5f) // @@@ FIXME ship.pos = (ship.pos * 0.5f) + (desiredPos * 0.5f) // @@@ FIXME ship.angle = angle ship.angle = angle } } fuse.update(dt) } } } } class Spark( class Spark( var lifetime: Float, var ttl: Float, collides: Boolean = false, collides: Boolean = false, mass: Float = 0f, mass: Float = 0f, val style: Style = Style.LINE, val style: Style = Style.LINE, val color: Color = Color.Gray, val color: Color = Color.Gray, val size: Float = 2f val size: Float = 2f, ) : Removable, Body() { val fuse: Fuse = Fuse(ttl) ) : Removable by fuse, Body(name = "Spark") { enum class Style { enum class Style { LINE, LINE, LINE_ABSOLUTE, LINE_ABSOLUTE, Loading @@ -398,10 +408,7 @@ class Spark( } } override fun update(sim: Simulator, dt: Float) { override fun update(sim: Simulator, dt: Float) { super.update(sim, dt) super.update(sim, dt) lifetime -= dt fuse.update(dt) } override fun canBeRemoved(): Boolean { return lifetime < 0 } } } } Loading Loading @@ -486,11 +493,11 @@ class Spacecraft : Body() { // exhaust // exhaust sim.add( sim.add( Spark( Spark( lifetime = sim.rng.nextFloatInRange(0.5f, 1f), ttl = sim.rng.nextFloatInRange(0.5f, 1f), collides = true, collides = true, mass = 1f, mass = 1f, style = Spark.Style.RING, style = Spark.Style.RING, size = 3f, size = 1f, color = Color(0x40FFFFFF) color = Color(0x40FFFFFF) ) ) .also { spark -> .also { spark -> Loading
packages/EasterEgg/src/com/android/egg/landroid/VisibleUniverse.kt +10 −2 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,7 @@ import androidx.compose.ui.util.lerp import androidx.core.math.MathUtils.clamp import androidx.core.math.MathUtils.clamp import com.android.egg.flags.Flags.flagFlag import com.android.egg.flags.Flags.flagFlag import java.lang.Float.max import java.lang.Float.max import kotlin.math.exp import kotlin.math.sqrt import kotlin.math.sqrt const val DRAW_ORBITS = true const val DRAW_ORBITS = true Loading Loading @@ -289,7 +290,8 @@ fun ZoomedDrawScope.drawLanding(landing: Landing) { fun ZoomedDrawScope.drawSpark(spark: Spark) { fun ZoomedDrawScope.drawSpark(spark: Spark) { with(spark) { with(spark) { if (lifetime < 0) return if (fuse.lifetime < 0) return val life = 1f - fuse.lifetime / ttl when (style) { when (style) { Spark.Style.LINE -> Spark.Style.LINE -> if (opos != Vec2.Zero) drawLine(color, opos, pos, strokeWidth = size) if (opos != Vec2.Zero) drawLine(color, opos, pos, strokeWidth = size) Loading @@ -297,7 +299,13 @@ fun ZoomedDrawScope.drawSpark(spark: Spark) { if (opos != Vec2.Zero) drawLine(color, opos, pos, strokeWidth = size / zoom) if (opos != Vec2.Zero) drawLine(color, opos, pos, strokeWidth = size / zoom) Spark.Style.DOT -> drawCircle(color, size, pos) Spark.Style.DOT -> drawCircle(color, size, pos) Spark.Style.DOT_ABSOLUTE -> drawCircle(color, size, pos / zoom) Spark.Style.DOT_ABSOLUTE -> drawCircle(color, size, pos / zoom) Spark.Style.RING -> drawCircle(color, size, pos, style = Stroke(width = 1f / zoom)) Spark.Style.RING -> drawCircle( color = color.copy(alpha = color.alpha * (1f - life)), radius = exp(lerp(size, 3f * size, life)) - 1f, center = pos, style = Stroke(width = 1f / zoom) ) } } } } } } Loading