雑念日記

主に技術的なことをつらとらと(書ければいいな)。

Processing 3 を ruboto で動かす => ruby-processing for Android だ!だ!

Ruby で Processing 用のコードを書いて Android で動かすという試み。

前々から、出来そうだからやってみたいなーと思っていたけど、ようやくやってみた。

結果

こんなコードを

class Sketch < PApplet
  def setup
    @pg = create_graphics(100, 100)
    @img_1 = load_image("weapon.png")
    @img_2 = load_image("potion.png")
  end

  def draw
    # 四角や丸を描画します
    background(150)
    stroke(0, 0, 0)
    rect(100, 100, 100, 100)
    stroke(125, 0, 0)
    rect(200, 200, 100, 100)
    stroke(255, 0, 0)
    ellipse(300, 300, 100, 100)

    # PGraphics を描画します
    @pg.begin_draw()
    @pg.background(100)
    @pg.stroke(255)
    @pg.line(@pg.width * 0.5, @pg.height * 0.5, mouseX, mouseY)
    @pg.end_draw()
    image(@pg, 0, 0)

    # ロードした画像を描画します
    image(@img_1, 50, 300)
    image(@img_2, 50, 350)
  end
end

apk にビルドして

f:id:hoshi_sano:20151116135418p:plain

こうじゃ!

このサンプル

f:id:hoshi_sano:20151116135436p:plain

こんなじゃ!

ソースコードはこちら。

github.com

※注)あんまり動作確認してません。

概要

キーワードは以下。

ruboto は RubyAndroid アプリ開発しちゃおうぜというプロジェクト。 Java で書かれた処理系である JRuby を使うことで、Android APIRuby の橋渡しをしている。

Processing はアート、データ可視化、ゲームといった分野に特化したプログラミングの言語/環境/ツール。 通常その成果物は Java アプリケーションとして出力されるが、モードを追加することで、ブラウザ上で動作する web 版であったり Android 端末上で動作する apk 版を出力することが可能となる。

これらを組合せ、ruboto を使って Android 版 Processing を実行することで、Android 上で動作するアートなコードを Ruby で書けちゃうぜっつー話。

モチベーションとかメリットとか

Ruby でお気楽に Android 上で動作するアプリを書きたかった。

元々 Processing の Ruby ラッパーとして、同じように JRuby を利用した ruby-processing*1というよく出来たプロダクトがあるのだけれど、これが現状では Java アプリケーション出力専用みたいな感じになっていて、Android 版への転用は難しそうだった。

別に Processing 使わなくても ruboto でアプリ書けばいいじゃんという話になりそうだけど、ruboto を使うにも Activity とかそのライフサイクルとか View とか、一定の Android アプリ開発の知識が必要そうだった。そういうのをナシに、もっとお気楽に Ruby で(グラフィカルな)アプリが動く!というトコロまで行ける何かが欲しかった。

ruboto の Github Organization アカウントに、ruboto-processing というやりたいことが既に実現できてそうなリポジトリがあったのだけれど、最終コミットが5年前とかでどう見ても obsolute です本当にありがとうございましたな状態だった。

仕組み

ruboto を使うと RubotoActivity という、JRuby の起動とか Ruby スクリプトの読み込みとか諸々の面倒を見てくれる Activity を利用することができる。この RubotoActivity を経由して、Ruby で記述されたスケッチ(Processing の作品をこう呼ぶ)を実行しているのが今回の成果物。

ところで、以前公開した記事の中で次のようなことを書いたことがある。

Processing Androidモードでは、スケッチのベースとなるPAppletクラスがAcitiviyを継承しているため、PAppletはAcitivityとして扱える。そして、スケッチをAndroid用にエクスポートしたファイルでは、以下のようにファイル名と同名のクラスがPAppletを継承しているため、これもやはりAcitivityとして扱える。

当時これは正しかったが、このコミットから PApplet クラスは Fragment のサブクラスとして扱われるようになっている。

そのため、今回の成果物では、RubotoActivity を継承した ProcessingRunActivity 上で、PApplet を継承した Sketch のインスタンスを Fragment として走らせるような構造となっている。

余談

PApplet が Activity のサブクラスだった頃の processing-core.jar を使って、Processing 2.x 向けに同じようなことを実現したソースコードも用意した。

github.com

こっちは RubotoActivity を継承した ProcessingRunActivity から、PApplet を継承した ProcessingSketchActivity を起動する、みたいな構造になっている。

けど、Java 側のクラスから見えている世界と Ruby 側のクラスから見えている世界との違いとかにいろいろ戸惑って、だいぶんイケてない作りになってる。たぶんちゃんと使おうと思ったらいろいろバグが出ると思う。

この実装方針を取らざるを得ないのか、もっといいやり方があるのかどうかも、Java 力と JRuby 力が低くてよくわからん。旧バージョン向けなので、そのあたりしっかり作りこむ気も起きない(言い訳)。

2.x 向けの方は参考程度に使ってやってください。

*1:JRubyArt という ruby-processing の先行版があるので、興味のある人はこちらをチェックすべきかも。いずれにせよ Android への転用はできなさそう。