It’s been a while since I’ve written these Java / Kotlin comparisons and today I felt like doing this, so here I am
Processing / Java
The original Bouncy Bubbles was written by Keith Peters / bit101. It was nice to discover this. He was an inspiring developer creating really cool stuff with Macromedia Flash back in the day, and he is still posting his experiments almost daily.
The code is quite simple, about 90 lines of code, featuring a Ball class with a constructor and three methods: collide, move and display.
OPENRNDR / Kotlin
Here is how I converted the code to Kotlin / OPENRNDR. Not much has changed, but lets look at the differences. I recommend viewing both versions side by side.
One thing to note is that Vector classes in OPENRNDR are not mutable, so you can’t just change their x
or y
value. That’s why velocity
is a var
, so I can rewrite it with a new value (by using +=
or *=
for instance).
Using vector arithmetic makes the code shorter, because I do not need to operate on the x
and y
components separately: I can just add velocity
to the position
, for instance.
Another thing that makes the code shorter is that in Kotlin it’s easy to declare variables and initialize them at the same time. The balls
array, which was declared at the top and then initialized in setup
, is now just one line of code.
Also the Ball()
constructor is much simpler, also just one line starting with class Ball(...
instead of having a separate constructor like in Java.
I took the liberty to do two small changes regarding the collide
method. One is to keep a safeArea
variable per ball. This area equals the drawer bounds minus the radius of the ball. This allow me to write position = position.clamp(safeArea)
, instead of writing various x
and y
values depending on if the ball tries to escape left, right, up or down. The other minor change is about how friction
is applied when hitting the borders: instead of checking if the value is less than radius
or greater than width - radius
, I check if the value is outside a range. I liked how that reads: if the x value is outside of the valid range, bounce.
imports
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extra.noise.Random
import org.openrndr.extra.noise.shapes.uniform
import org.openrndr.math.Vector2
import org.openrndr.shape.clamp
fun main() = application {
configure {
width = 640
height = 360
}
program {
val numBalls = 12
val spring = 0.05
val gravity = Vector2(0.0, 0.03)
val friction = -0.9
class Ball(var position: Vector2, val radius: Double, val id: Int) {
var velocity = Vector2.ZERO
val safeArea = drawer.bounds.offsetEdges(-radius)
fun collide(others: List<Ball>) {
for (i in id + 1 until numBalls) {
val diff = others[i].position - position
val minDist = others[i].radius + radius
if (diff.length < minDist) {
val targetPos = position + diff.normalized * minDist
val acceleration = (targetPos - others[i].position) * spring
velocity -= acceleration
others[i].velocity += acceleration
}
}
}
fun move() {
velocity += gravity
position += velocity
if (position.x !in radius..width - radius) {
velocity *= Vector2(friction, 1.0)
}
if (position.y !in radius..height - radius) {
velocity *= Vector2(1.0, friction)
}
position = position.clamp(safeArea)
}
fun display() {
drawer.circle(position, radius)
}
}
val balls = List(numBalls) { Ball(drawer.bounds.uniform(), Random.double(15.0, 35.0), it) }
extend {
drawer.clear(ColorRGBa.BLACK)
drawer.stroke = null
drawer.fill = ColorRGBa.WHITE.opacify(0.8)
balls.forEach {
it.collide(balls)
it.move()
it.display()
}
}
}
}
Online version in JavaScript?
In the good(?) old times, one could create Processing programs and post them online as Java Applets. This stopped working long time ago. Flash also is gone. So what if you want to share your OPENRNDR creations online?
openrndr-js-template to the rescue! It does not offer 100% of the functionality we have in the JVM side of things, but it does offer a lot. It takes advantage of the Multi-Platform capabilities of Kotlin to produce a JavaScript version of your program.
The small programs I experimented with produced files of ~300Kb. Not quite as small as with plain JavaScript, but much better than in my previous attempts with other frameworks, which produced files many megabytes heavy. Also much better than any news website out there
Run a the above program in your browser
Normally OPENRNDR programs run locally in your computer. How did I create a web version? Quite simple:
- Clone the JS template repo with
git clone -b next-version https://github.com/openrndr/openrndr-js-template.git
- Write your program in
src/commonMain/kotlin/TemplateProgram.kt
- See the instructions on how to run / publish a production version (HTML+JS)
- Finally upload the result to a web server (I used GitHub pages in this case)
In the next weeks I plan to continue experimenting to see how much can one do with the JS version and post them online.
Share your questions and comments below .
Find other OPENRNDR & Processing posts