Kotlin 9
The story is this:
- Ship accelerates along its forward axis;
To do that, I think we need the ability to add acceleration to velocity. This is getting a bit silly, I think. I already have a position object, Coordinates, and a Velocity object and now, in principle, I need an acceleration object. I could, of course, just do the math: it’s all vector arithmetic, where you keep track of the data types in your head.
I’m gonna go ahead and do it.
class AccelerationTest {
@Test
fun scaling() {
val v = Velocity(100.0,200.0)
val a = Acceleration(15.0, 25.0)
val vAccelerated = v + a
Assertions.assertThat(vAccelerated.dx).isEqualTo(115.0)
Assertions.assertThat(vAccelerated.dy).isEqualTo(225.0)
}
}
data class Acceleration(val d2x: Double, val d2y:Double) {
operator fun times(scale: Double) : Acceleration {
return Acceleration(d2x*scale, d2y*scale)
}
}
data class Velocity(val dx: Double = 0.0, val dy: Double = 0.0) {
...
operator fun plus(a: Acceleration) : Velocity {
return Velocity(dx+a.d2x, dy+a.d2y)
}
}
Tests are green. Let me commit and then perhaps explain. Commit: Acceleration class can adjust Velocity via addition v+a.
I see that I have no test for scaling, I thought I would use it but then I didn’t. Let me adjust the test and results.
class AccelerationTest {
@Test
fun scaling() {
val v = Velocity(100.0,200.0)
val a = Acceleration(60.0, 100.0)
val aScaled = a*0.25
val aExpected = Acceleration(15.0, 25.0)
assertThat(aScaled).isEqualTo(aExpected)
val vAccelerated = v + aScaled
assertThat(vAccelerated.dx).isEqualTo(115.0)
assertThat(vAccelerated.dy).isEqualTo(225.0)
}
}
OK, test still runs. Commit: added test for acceleration scaling.
Now let’s talk. I got ahead of myself.
I imagine that acceleration will be expressed in SpaceUnits per second per second, and, like we need to do with Velocity when we move the Ship, we’ll need to scale that raw value by delta time. Now I am definitely writing speculative code here, and I may wind up regretting it, but something about the way I’ve started, the commitment I have to doing all this before I handle the graphics, and the way that Kotlin leans on my mind … all those things are leading me to work in this bottom up fashion, which leads me, when I’m not cautious, to speculative implementation.
Anyway, now I think I can write a Ship test for acceleration, since I have one for all the relevant associated classes.
@Test
fun shipAccelerates() {
val universe = Universe(4000.0,3000.0)
val ship = Ship(universe, Coordinates(0.0, 0.0))
ship.setVelocity(10.0,20.0)
val a = Acceleration(5.0, 7.0)
ship.accelerate(a, 1000.0)
val ev = Velocity(15.0, 27.0)
assertThat(ship.velocity).isEqualTo(ev)
}
It just remains to write accelerate
on Ship. Then I’ll tell you what I don’t like about this.
fun accelerate(acceleration: Acceleration, timeMS: Double) {
val scale = timeMS/1000.0
val scaledAcceleration = acceleration*scale
velocity += scaledAcceleration
}
Tests are green. Commit: ship can accelerate.
OK. What I don’t like about this is that I don’t have a good sense of how the ship will really be used in the game. I can guess that each cycle, we’ll apply an acceleration due to gravity, and any acceleration due to the ship’s engines, but I don’t have a sense of just how I’ll want to say those things. Instead, I’m providing general facilities on my Coordinates, Velocity, and Acceleration classes. Those facilities will pretty clearly do anything I need, but will they be convenient? I don’t know, and that bugs me.
I guess we’ll find out soon.
For now, this afternoon’s bonus article, this will do.
Summary
I think I’m getting at least some aspects of Kotlin and IDEA under my belt. I’m not incredibly fast yet but I pretty much knew what I had to do and where to do it. Inch by inch.
See you next time!