物理エンジン Chipmunk + Gosu でごく簡単なドミノ倒しみたいな動画を作ってみました。Ruby 2.3.3, Linux Mint 18.3 で確認しました。
gosu_chipmunk_sample3.rb
require 'gosu' require 'rmagick' require 'chipmunk' CV = CP::Vec2 Width, Height = 500, 200 Wall_h = 50 BOD_w, BOD_h = 20, 100 class MyWindow < Gosu::Window def initialize super Width, Height, false self.caption = "Gosu + Chipmunk" @space = CP::Space.new @space.iterations = 3 @space.gravity = CV.new(0, 100) background = Magick::Image.new(Width, Height) {self.background_color = "snow"} #地面 gc = Magick::Draw.new gc.fill('firebrick') gc.rectangle(0, Height - Wall_h, Width, Height) gc.draw(background) #板 board_image = Magick::Image.new(BOD_w, BOD_h) gc = Magick::Draw.new gc.fill('lightgreen') gc.rectangle(0, 0, BOD_w, BOD_h) gc.draw(board_image) @board = Gosu::Image.new(board_image) #円 circle_image = Magick::Image.new(11, 11) {self.background_color = 'transparent'} gc = Magick::Draw.new gc.fill('skyblue') gc.circle(5, 5, 0, 5) gc.draw(circle_image) @circle = Gosu::Image.new(circle_image) #chipmunk #地面 sb = CP::Body.new_static x1, y1 = 0, Height - Wall_h x2, y2 = Width, Height verts = [CV.new(x1, y1), CV.new(x1, y2), CV.new(x2, y2), CV.new(x2, y1)] wshape = CP::Shape::Poly.new(sb, verts, CV.new(0, 0)) wshape.e = 1 wshape.u = 1 @space.add_shape(wshape) #板 set_boards(5) #円 @bodyc = CP::Body.new(7, CP::INFINITY) @bodyc.p = CV.new(0, 20) @bodyc.v = CV.new(50, 0) shape = CP::Shape::Circle.new(@bodyc, 5, CV.new(0, 0)) shape.e = 0.8 shape.u = 0 @space.add_body(@bodyc) @space.add_shape(shape) @background_image = Gosu::Image.new(background) end def set_boards(n) @boards = [] n.times do |i| x, y = BOD_w / 2.0, BOD_h / 2.0 bx = [CV.new(-x, -y), CV.new(-x, y), CV.new(x, y), CV.new(x, -y)] body = CP::Body.new(10, CP.moment_for_poly(10, bx, CV.new(0, 0))) body.p = CV.new(50 + 80 * i, Height - Wall_h - y) shape = CP::Shape::Poly.new(body, bx, CV.new(0, 0)) shape.e = 0 shape.u = 1 @space.add_body(body) @space.add_shape(shape) @boards << body end end def update @space.step(1.0 / 60) end def draw @background_image.draw(0, 0, 0) @boards.each do |b| @board.draw_rot(b.p.x, b.p.y, 2, (b.a - Math::PI / 2).radians_to_gosu) end @circle.draw_rot(@bodyc.p.x, @bodyc.p.y, 1, 0) end end MyWindow.new.show
パラメータの調節がむずかしかったですね。それぞれの質量の値は重要です。長方形はあんまり軽すぎると不安定になったりします。