ruby-processingでrandom_boxを作ってみる

 ここん所はprocessingをいじっているわけですが、「Built with Processing —デザイン/アートのためのプログラミング入門」の、chapter4で著者の前川さんが作成されたサンプルコードが出ていてそれが面白そうなので*1早速ruby-processingで写経してみる。


 では、いつも通り。

rp5 create random_box.rb 400 400

雛形を作成して、Let's Processing>A<

1st step

 最初に、整列したrectを表示する部分を作成します。
今回は、最初に作成される雛形以外に、縦20×横20の個々のboxを表現するためDot*2クラスを作成します。

注意

ruby-processingでProcessingAPI等は、Processing::Appクラスを継承したクラスからしか使用できません*3
ですので、Dotクラスのメソッドで、rectやfill等のProcessingAPIは使用できないことになります。

では、どうするのかという事ですがProcessing::Appクラスを継承しているRandomBoxクラスの参照を、Dotクラスに渡してやります。
Dotクラスからは、メンバのRandomBoxクラス参照を経由して、ProcessingAPIを使用します*4

# Random Box

class Dot
  def initialize app,w,h,x,y
    @app,@w,@h,@x,@y = app,w,h,x,y
    @sx,@sy=x,y
    @pressed = 0
  end
  
  def move
    case @pressed
    when 0
    when 1
      @x += @app.random(-5,5)
      @y += @app.random(-5,5)
    when 2
      @x = @sx
      @y = @sy
    else
    end
    
  end
  
  def display
    @app.fill 200
    @app.rect @x,@y,@w,@h
  end
  
  def pressed
    @pressed += 1
    @pressed = 0 if @pressed > 2
  end
  
  def released
  end
end


class RandomBox < Processing::App
  
  def setup
    smooth
    frame_rate 15

    @ary = []
    grid 20,20,10,10 do |x,y|
      @ary << Dot.new(self,5,5,x+100,y+100)
    end
  end
  
  def draw
    background 0
    @ary.each{|dot|
      dot.move
      dot.display
    }
  end
  
  def mouse_pressed
    @ary.each{|dot| dot.pressed}
  end
  def mouse_released
    @ary.each{|dot| dot.released}
  end
  
end

RandomBox.new :title => "Random Box", :width => 400, :height => 400

 はい、整列したBoxと、そのBoxがマウスによりランダムに動き出す部分までは、作成できました。

2nd step

 次に、ランダムに動いているBoxが元の位置に戻るところまでを作成します。

# Random Box

class Dot
  def initialize app,w,h,x,y,color
    @app,@w,@h,@x,@y,@color = app,w,h,x,y,color
    @sx,@sy=x,y
    @pressed = 0
  end
  
  def move
    check_position
    case @pressed
    when 0
      @x = @sx
      @y = @sy
    when 1
      @x += @app.random(-5,5)
      @y += @app.random(-5,5)
    when 2
      @x -= ((@x - @sx) * 0.05)
      @y -= ((@y - @sy) * 0.05)
    else
    end
  end
  
  def display
    @app.fill @color
    @app.rect @x,@y,@w,@h
  end
  
  def pressed
    @pressed += 1
    @pressed = 0 if @pressed > 2
  end
  
  def released
  end
  
  private
  
  def check_position
    @x = 0           if @x > @app.width
    @x = @app.width  if @x < 0
    @y = 0           if @y > @app.height
    @y = @app.height if @y < 0
  end
end


class RandomBox < Processing::App

  def setup
    smooth
    frame_rate 15

    @ary = []
    grid 20,20,10,10 do |x,y|
      @ary << Dot.new(self,5,5,x+100,y+100,color(random(255),random(255),random(255)))
    end
    
  end
  
  def draw
    background 0
    @ary.each{|dot|
      dot.move
      dot.display
    }
  end
  
  def mouse_pressed
    @ary.each{|dot| dot.pressed}
  end
  def mouse_released
    @ary.each{|dot| dot.released}
  end
  
end

RandomBox.new :title => "Random Box", :width => 400, :height => 400

 うん、大丈夫ですね。

3rd step

 最後に、ランダムな動きから、円の動きへの変化するのを作成してみます。

# Random Box

class Dot
  include Math
  
  def initialize app,w,h,x,y,color,count
    @app = app
    @w,@h,@x,@y = w,h,x,y
    @color = color
    @count = count
    @sx,@sy=x,y
    @pressed = 0
  end
  
  def move
    check_position
    case @pressed
    when 0
      @x -= ((@x - @sx) * 0.05)
      @y -= ((@y - @sy) * 0.05)
    when 1
      @x += @app.random(-5,5)
      @y += @app.random(-5,5)
    when 2 #想定した円の動きになりました^^
      @x -= ((@x - @app.width/2 + 200*sin(@app.frame_count / -180.0 * PI + @count)) * 0.01)
      @y -= ((@y - @app.height/2 +200*cos(@app.frame_count / -180.0 * PI + @count)) * 0.01)
    when 3 #想定とは違うけど面白い動きなので置いておく
      @x -= ((@x - @app.width/2 + 100*sin(@count*@app.frame_count)) * 0.05)
      @y -= ((@y - @app.height/2 +100*cos(@count*@app.frame_count)) * 0.05)
    when 4
      @x -= ((@x - @app.width/2 + 200*sin((@app.frame_count+@count)/30)) * 0.1)
      @y -= ((@y - @app.height/2 +200*cos((@app.frame_count+@count)/30)) * 0.1)
    end
  end
  
  def display
    @app.fill @color
    #@app.rect_mode @app::CENTER
    @app.rect @x,@y,@w,@h
  end
  
  def pressed
    @pressed += 1
    @pressed = 0 if @pressed > 4
  end
  
  def released
  end
  
  private
  
  def check_position
    @x = 0           if @x > @app.width
    @x = @app.width  if @x < 0
    @y = 0           if @y > @app.height
    @y = @app.height if @y < 0
  end
end


class RandomBox < Processing::App

  def setup
    smooth
    frame_rate 15

    @ary = []
    count = 0
    grid 20,20,10,10 do |x,y|
      @ary << Dot.new(self,5,5,x+100,y+100,color(random(255),random(255),random(255)),count)
      count+=1
    end
    
  end
  
  def draw
    background 0
    @ary.each{|dot|
      dot.move
      dot.display
    }
  end
  
  def mouse_pressed
    @ary.each{|dot| dot.pressed}
  end
  
  def mouse_released
    @ary.each{|dot| dot.released}
  end
  
end

RandomBox.new :title => "Random Box", :width => 400, :height => 400

 う〜ん、作りたかった動作に行き着く間に、いろいろ面白い動作が確認できました。

conclusion

 簡単なProcessingですが、やっぱり想定した動作をさせるには練習あるのみですね^^;
しかしBuilt with Processingの見た目がアート系の書籍だったのでプログラムに関してサラッとした本なのかなと、思ってましたが、しっかりProcessingプログラム入門していて読み応え*5十分でした。一先ず借り物なので今週中に読み終わらないといけないんだけど、読み終わるかなw;
 まあ、改訂版がでているらしいのでそっち買ってもいいかな^^

Built with Processing —デザイン/アートのためのプログラミング入門
前川 峻志 田中 孝太郎
ビー・エヌ・エヌ新社
売り上げランキング: 235223
おすすめ度の平均: 4.0
3 未購入だけど
4 プログラミングの入門者に最適!
5 わかりやすい
Built with Processing [改訂版]
前川 峻志 田中 孝太郎
ビー・エヌ・エヌ新社
売り上げランキング: 30947
おすすめ度の平均: 3.5
3 デザインとアートだけに使っていてはもったいない言語
4 さっそく改訂版を買いました

*1:プログラムの製作意図とそのプログラムを作るため、何のProcessingコードを参考にしてどのように作り上げていかれたかの過程を書いている面白い記事です

*2:Boxクラスにすればよかったw;

*3:と思います^^;

*4:他のいい方法があれば教えて偉い人>A<

*5:フルカラーで実行結果の表示の図等も一杯なのにProcessingの基本から応用まで一通り網羅しています