Kotlin+Processingのススメ

初めまして。

今回、音ゲーイベントの「BOFU2016」に自作曲を1曲出すことになりまして、その曲のBGA(所謂MVですね)をProcessingで作ってみることにしました。Kotlin信者である私は当然開発言語にKotlinを選んだわけですが、作ってみると思っていた以上にKotlinの機能が活用できることが分かったのでここに書き留めておきたいと思います。

ちなみに宣伝になりますが、私の作品はこちらです。音ゲーマーの皆さんは是非プレイしてくださいね。 http://manbow.nothing.sh/event/event.cgi?action=More_def&num=302&event=110

導入方法は[ProcessingをIntelliJ IDEA+Kotlinで書く](http://qiita.com/nonsako/items/c193b2eddd9f38bd7844)に詳しいため省略します。

さらば執拗なドット(`.`)
====

シーン別にクラスを定義して、描画をそれぞれで行いたいという時、普通はこんな感じで書くと思います。

```kotlin
class MyApplet: PApplet() {
  // scenes: Array<Scene>
  override fun draw() {
    scenes.forEach { it.draw(this) }
  }
}

class Scene1(): Scene {
  override fun draw(app: MyApplet) {
    app.noStroke()
    app.fill(1f)
    app.pushMatrix()
    app.translate(640f, 360f)
    app.rect(-50f, -50f, 100f, 100f)
    // ...
  }
}
```

この`app.`、邪魔じゃないですか？
そこで`with()`を使います。

```kotlin
class Scene1(): Scene {
  override fun draw(app: MyApplet) {
    with(app) {
      noStroke()
      fill(1f)
      pushMatrix()
      translate(640f, 360f)
      rect(-50f, -50f, 100f, 100f)
      // ...
    }
  }
}
```

`with(app)`内では`this`=`app`なので、`app.draw()`内で描画コードを呼び出しているかのように扱うことができるのです。

この手法は同様に`PGraphics`にも使えます。`PApplet`と`PGraphics`で描画のメソッド名は同じなので、直接描画していたものをバッファに描画したいという時などは(その逆も)、該当コードを`with()`で括ってしまえばいいわけです。

`PGraphics`に描画する時によく`beginDraw()` `endDraw()`し忘れるそこのあなた。このような関数を定義してしまえば、

```kotlin
inline fun <R> withGraphics(receiver: PGraphics, f: PGraphics.() -> R) {
  receiver.beginDraw()
  receiver.f()
  receiver.endDraw()
}
```

```kotlin
class MyScene(val app: MyApplet) {
  val g = app.createGraphics(1280, 720)
  
  override fun draw(app: MyApplet) {
    with(app) {
      withGraphics(g) {
        noStroke()
        fill(1f)
        pushMatrix()
        translate(640f, 360f)
        rect(-50f, -50f, 100f, 100f)
        // ...
      }
    }
  }
}
```

`withGraphics()`で囲むだけ。労力最小ですね。

`with(app)`の中にネストすることで、各種数学関数(`sin`, `norm`, ...)なども同様に使えます。

関数
====

Processingやってると、単純なイージング関数とか、作りたくなりますよね。関数型言語のエッセンスを取り入れたKotlinなら、`{}`や`return`無しで簡単に書けてしまいます。

```kotlin
class MyApplet: PApplet() {
  // ...

  // 二次
  fun quad1(t: Float) = -t * (t - 2f)
  // n次
  fun pow1(t: Float, e: Float) = -pow(-t + 1f , e) + 1f

　// 範囲外の値を取らないnormを定義 (おすすめ！)
  fun cnorm(value: Float, start: Float, stop: Float) = constrain(norm(value, start, stop), 0f, 1f)
}
```
```kotlin
// 16拍目から18拍目までで二次のイーズイン
val t = cnorm(beat, 16f, 18f)
val s = quad1(t)
tint(lerp(0.5f, 0f, s))
```

描画系メソッドを拡張できる
====

```kotlin
// 整数座標に直して画像を描画する(パフォーマンスアップ)
fun PGraphics.iimage(img: PImage, x: Float, y: Float) = this.image(img, x.toInt().toFloat(), y.toInt().toFloat())

class MyScene(val app: MyApplet) {
  val g = app.createGraphics(1280, 720)

  override fun draw(app: MyApplet) {
    with(app) {
      withGraphics(g) {
        iimage(img, 0.5f, 0.5f)
        // ...
      }
    }
  }
}
```

スクリーンへの描画を拡張する時は、同様に`PApplet`に対して拡張関数を定義するか、PAppletを継承したクラスにメソッドを定義しましょう。

もうpopし忘れない
====

```kotlin
inline fun <R> PGraphics.saveMatrix(f: () -> R) {
  this.pushMatrix()
  f()
  this.popMatrix()
}
```

こんな風に定義しておけば、

```kotlin
saveMatrix {
  translate(640f, 360f)
  scale(1.5f)
  rotate(PI / 4)
  // ...
  saveMatrix {
    rotate(PI / 8)
    // ...
  }
  saveMatrix {
    rotate(-PI / 8)
    // ...
  }
}
```

`saveMatrix`で括られた部分をブロックのように扱え(実際はラムダを渡しているのですが)、行列が保存されている部分がネストされて読みやすいし、`popMatrix()`を忘れてしまうというミスが起きないのです。

同様に`PApplet`にも定義しておきましょう。

----

如何でしたか？
Javaで疲弊した人、是非KotlinでProcessingしてみてください。
間違いを見つけた方や「こんな使い方もあるよ！」という方はコメントしてください。お待ちしています。