mrubyでお絵描きプログラミング!10分ではじめるRubyKokuban

この記事はmruby Advent Calendar 2013の16日目です。

はじめに

少し前にRubyKokubanというものを作りました。

このライブラリを使うと、簡単にグラフィックやアニメーションを使ったアプリケーションを書くことが出来ます。

RubyKokubanとは

RubyKokubanはopenFrameworksにmrubyを組み込んだものです。Rubyを使って簡単にグラフィックスやアニメーションを利用したプログラムを書くことが出来ます。

以下のように、(関数定義を除けば)2行で画面に文字と円を表示することが出来ます。

def draw
  text 'Hello, rubykokuban!', 100, 100
  circle 350, 100, 50
end

demo-01.png

たくさん書いてみます。

def setup
  set_window_size 200, 200
  set_background Color::Black
end

def draw
  (1..100).each do
    set_color rand(255), rand(255), 128, 128
    circle rand(200), rand(200), rand(10) + 20
  end
end

f:id:tuto0621:20131215152748p:plain

動いた!といいたい所ですがdrawが毎F呼ばれているために円が高速に書き換えられてしまいます。 ※ 後で直します

f:id:tuto0621:20131215152810g:plain

RubyKokubanがどんなものなのかは伝わったと思うので、バグは放置してインストール方法を紹介します。

RubyKokubanを使うための準備

RubyKokubanを使うには以下の手順が必要です。

  1. kokuban gem をインストールする
  2. RubyKokubanをダウンロードする
  3. コードをテキストファイルに書く
  4. kokubanコマンドを使って実行する

rubyコマンドの代わりにkokubanコマンドを使う感じです。それではやってみましょう。

kokuban gem をインストールする

RubyGemsからインストールします。

$ gem install kokuban 

kokubanコマンドが使えるようになれば成功です。

$ kokuban
kokuban 0.2.0

Commands:
  kokuban exec [input_file]  # Execute rubykokuban file
  kokuban help [COMMAND]     # Describe available commands or one specific command
  kokuban install [options]  # Install RubyKokuban.app
  kokuban list               # Display installed version
  kokuban uninstall          # Uninstall rubykokuban from the local repository

Options:
  -h, [--help]  # Help message

RubyKokubanをダウンロードする

$ kokuban install --latest

各プラットホーム用にビルドされたクライアントがダウンロードされます。現在はMacのみ対応しています。

※ openFrameworks自体はWindows, Linuxに対応しているのでongaeshi/rubykokuban-osxを参考にすれば移植は可能だと考えています。誰かやってくれたら嬉しいなぁ。

コードを書く

以下のコードをhello.rbという名前で保存します。(テキストファイルは好きなもので構いません)

def setup
  set_window_size 300, 300
  set_background Color::White
end

def draw
  set_fill

  set_color Color::Red, 128
  rect 70, 70, 60, 60

  set_color Color::Green, 128
  circle 200, 100, 30

  set_color Color::Blue, 128
  triangle 150 - 30, 200, 150 + 30, 200, 150, 200 + 52
end

実行する

kokuban execコマンドで実行します。3つの図形が出たら成功です。

$ kokuban exec hello.rb

f:id:tuto0621:20131215153105p:plain

調整する

楕円を追加してみます。

def draw
  .
  .
  set_color Color::Blue, 128
  triangle 150 - 30, 200, 150 + 30, 200, 150, 200 + 52
+
+  set_color Color::Black
+  set_no_fill
+  ellipse 150, 150, 200, 270

ここでポイントです!

書き換えたら閉じずにウィンドウにフォーカスを合わせてCtrl+Rを押します。 自動リロードされるので開発がとても快適になります。

f:id:tuto0621:20131215153120p:plain

なにか書いてみよう

最初のサンプルをちゃんとする

最初のサンプルに戻りましょう。

def setup
  set_window_size 200, 200
  set_background Color::Black
end

def draw
  (1..100).each do
    set_color rand(255), rand(255), 128, 128
    circle rand(200), rand(200), rand(10) + 20
  end
end

円が高速に書き換えられてしまう問題を修正します。 setupで事前に描画用のデータを作りdrawはそれを表示するだけに改造してみます。

class Shape < Struct.new(:x, :y, :radius, :color); end

def setup
  set_window_size 200, 200
  set_background Color::Black
  set_fill

  @shapes = []
  (1..100).each do
    @shapes << Shape.new(rand(200), rand(200), rand(10) + 20,
                         Color.new(rand(255), rand(255), 128, 128))
  end
end

def draw
  @shapes.each do |d|
    set_color d.color
    circle d.x, d.y, d.radius
  end
end

f:id:tuto0621:20131215152748p:plain

コードは少し長くなりましたが大分見通しのよいコードになりました。

  • Shapeという描画用データを保持するための型が定義
  • @shapes配列が生成情報を管理
  • draw関数は配列のデータを受け取ってそのまま表示

インタラクティブにする

Rubyの表現力の高さを活かして少し複雑な動きを書いてみましょう。

マウスカーソルがウィンドウにある時は円がカーソルに近づき、ウィンドウから出たら元の位置に戻るようなデモを書いてみます。

f:id:tuto0621:20131215152953g:plain

元の位置に保存するためにShape#ox, Shape#oyメンバを追加します。update関数を追加してカーソルに追従したり元の位置に戻る処理を書きます。

class Shape < Struct.new(:x, :y, :radius, :color, :ox, :oy); end

def setup
  set_window_size 200, 200
  set_background Color::Black
  set_fill

  @shapes = []
  (1..100).each do
    s = Shape.new(rand(200), rand(200), rand(10) + 20,
                  Color.new(rand(255), rand(255), 128, 128))
    s.ox = s.x
    s.oy = s.y
    @shapes << s
  end
end

def update
  @shapes.each do |d|
    if 0 < Input.mouse_y && Input.mouse_y < 200 &&
        0 < Input.mouse_x && Input.mouse_x < 200 
      d.x += (Input.mouse_x - d.x) * 0.08
      d.y += (Input.mouse_y - d.y) * 0.08
    else
      d.x += (d.ox - d.x) * 0.2
      d.y += (d.oy - d.y) * 0.2
    end
  end
end

def draw
  @shapes.each do |d|
    set_color d.color
    circle d.x, d.y, d.radius
  end
end

繰り返しの処理をブロック構文ですっきりと書けるのはやはりいいですね。

もっと書きたい

以下にサンプルコードがあります。

シューティングゲームもありますよ。

mouse-shooting2

まとめ

グラフィックを操作するプログラミングはとても楽しいので是非一度触ってみて下さい。最新版では画像を表示することも出来るようになりました。

RubyKokubanのメリット

Rubyで書ける以外に何かいいことがあるのでしょうか?

CRubyやPythonでopenFrameworksをラップした場合、openFrameworksはライブラリとして提供され、CRubyやPythonからライブラリにアクセスすることになります。ユーザーからはRubyスクリプトしか見えませんがOSから見るとCRubyとopenFrameworksの二つのアプリケーションが連携していることになります。

mrubyでopenFrameworksを利用する場合mrubyはopenFrameworksの中に隠れます。OSから見るとopenFrameworksしか存在しないように見えます。提供する機能は違いますがOpenCVやBox2Dといった他のopenFrameworksのライブラリと本質的に違いはありません。RubyKokubanはRubyスクリプトを読み込んで実行するopenFrameworksアプリケーションなのです。

そのため、以下のようなメリットがあります。

  • 単独のアプリケーションとして動作させることが出来る
    • Rubyスクリプトを内部に組み込めば全てC++で書かれたものと違いはなくなる
  • 速度が重要な部分やまだ組み込まれていない機能はC++で書く事が出来る

参考文献