突然はなしが変わってRuby/Tkでアニメーションを作る話
今まで、マクロをRubyで実現する話を書いていたのですが、突然飽きて最近ActionScript方面でいろいろある物理シミュレーションをRubyで作ってみたくなったので色々やってみたいと思い立ちました。でも、物理は高校で止まっていて今日も図書館で物理の本を読んでみたのですが、ちんぷんかんぷんなので挫折する可能性大です。
とりあえず、ボールを斜め上に投げるよというものです。放物線を描いて地面に当たると弾みます。見るだけです。ボールが画面の外に出たらそれから先は何も起きません。
Ruby/Tkが必要ですが標準で入っているので、Tcl/Tkがインストールされていれば動くんじゃないかなと思います。でも、Ruby 1.9.0では動かなかったです。Ruby 1.8.6で試しています。
追記
プログラムを書き換えて一杯ボールが出るようにしました。しばらく待っているとボールが増えていきます。
require 'tk' require 'singleton' class Viewer<TkFrame include TkComposite WIDTH = 512 HEIGHT = 512 def initialize_composite @frame.configure(:width=>WIDTH, :height=>HEIGHT) @canvas = TkCanvas.new(@frame) @canvas.configure(:width=>WIDTH, :height=>HEIGHT) @canvas.grid('row'=>0, 'column'=>0, 'sticky'=>'news') @frame.grid_propagate(false) end def draw_oval(x, y, r) r2 = r / 2 TkcOval.new(@canvas, x - r2, HEIGHT - y + r2, x + r2, HEIGHT - y - r2, 'fill' => :red) end end class Field include Singleton def initialize @view = Viewer.new @view.pack(:expand=>true, :fill=>:both) end def draw_oval(x, y, r) @view.draw_oval(x, y, r) end end class Ball @@field = Field.instance def initialize(r, x, y, vx, vy) @x = x @y = x @r = r @vx = vx @vy = vy @shape = @@field.draw_oval(@x, @y, @r) end def redraw r2 = @r / 2 @shape.coords = [ @x - r2, Viewer::HEIGHT - @y + r2, @x + r2, Viewer::HEIGHT - @y - r2, ] end def compute_next_pos @x = @x + @vx @y = @y + @vy @vy = @vy - 0.1 if @y < 10 then @y = 10 @vy = (-@vy) * 0.97 end if @x > 600 then return false @shape.destroy end redraw return true end end objs = [] objs.push Ball.new(10, 10, 10, 1, 10) count = 0 objnum = 1 timer = TkAfter.start(10, -1, lambda { i = objnum count = count + 1 while i != 0 do i = i - 1 if objs[i].compute_next_pos == false then objs[i] = Ball.new(10, rand * 100, 10, 1, 10) end end if count % 780 == 0 then objs.push Ball.new(10, rand * 100, 10, 1, 10) objnum = objnum + 1 end }) Tk.mainloop