Gosu + Chipmunk + RMagick
Ruby Chipmunk Integration
Gem 'gosu-examples' が参考になる。bundle exec gosu-exapmles で OK!
chipmunk_and_rmagick.rb を実行するとよい。
chipmunk_and_rmagick.rb のコピペ。
# Encoding: UTF-8 # Based on the C Demo3 demonstration distributed with Chipmunk. # Also with some help from the chipmunk_integration.rb program. # # License: Same as for Gosu (MIT) # Created on 21/10/2007, 00:05:19 by Robert Sheehan require 'rubygems' require 'gosu' require 'chipmunk' require 'rmagick' # Layering of sprites module ZOrder BACKGROUND, BOX = *0..1 end WIDTH = 640 HEIGHT = 480 TICK = 1.0/60.0 NUM_POLYGONS = 80 NUM_SIDES = 4 EDGE_SIZE = 15 class ChipmunkAndRMagick < (Example rescue Gosu::Window) def radians_to_vec2(radians) CP::Vec2.new(Math::cos(radians), Math::sin(radians)) end def initialize super WIDTH, HEIGHT self.caption = "Chipmunk, RMagick and Gosu" @space = CP::Space.new @space.iterations = 5 @space.gravity = CP::Vec2.new(0, 100) # you can replace the background with any image with this line # background = Magick::ImageList.new("media/space.png") fill = Magick::TextureFill.new(Magick::ImageList.new("granite:")) background = Magick::Image.new(WIDTH, HEIGHT, fill) setup_triangles(background) @background_image = Gosu::Image.new(background, :tileable => true) # turn the image into a Gosu one @boxes = create_boxes(NUM_POLYGONS) end # Create all of the static triangles. # Adds them to the space and the background image. def setup_triangles(background) gc = Magick::Draw.new gc.stroke_width(2) gc.stroke('red') gc.fill('blue') # all the triangles are part of the same body body = CP::Body.new(Float::MAX, Float::MAX) base = 15 height = 10 shape_vertices = [CP::Vec2.new(-base, base), CP::Vec2.new(base, base), CP::Vec2.new(0, -height)] # make shapes and images 8.times do |i| 8.times do |j| stagger = (j % 2) * 40 x = i * 80 + stagger y = j * 70 + 80 shape = CP::Shape::Poly.new(body, shape_vertices, CP::Vec2.new(x, y)) shape.e = 1 shape.u = 1 @space.add_static_shape(shape) gc.polygon(x - base + 1, y + base - 1, x + base - 1, y + base - 1, x, y - height + 1) end end # do the drawing gc.draw(background) end # Produces the vertices of a regular polygon. def polygon_vertices(sides, size) vertices = [] sides.times do |i| angle = -2 * Math::PI * i / sides vertices << radians_to_vec2(angle) * size end return vertices end # Produces the image of a polygon. def polygon_image(vertices) box_image = Magick::Image.new(EDGE_SIZE * 2, EDGE_SIZE * 2) { self.background_color = 'transparent' } gc = Magick::Draw.new gc.stroke('red') gc.fill('plum') draw_vertices = vertices.map { |v| [v.x + EDGE_SIZE, v.y + EDGE_SIZE] }.flatten gc.polygon(*draw_vertices) gc.draw(box_image) return Gosu::Image.new(box_image) end # Produces the polygon objects and adds them to the space. def create_boxes(num) box_vertices = polygon_vertices(NUM_SIDES, EDGE_SIZE) box_image = polygon_image(box_vertices) boxes = [] num.times do body = CP::Body.new(1, CP::moment_for_poly(1.0, box_vertices, CP::Vec2.new(0, 0))) # mass, moment of inertia body.p = CP::Vec2.new(rand(WIDTH), rand(40) - 50) shape = CP::Shape::Poly.new(body, box_vertices, CP::Vec2.new(0, 0)) shape.e = 0.0 shape.u = 0.4 boxes << Box.new(box_image, body) @space.add_body(body) @space.add_shape(shape) end return boxes end # All the simulation is done here. def update @space.step(TICK) @boxes.each { |box| box.check_off_screen } end # All the updating of the screen is done here. def draw @background_image.draw(0, 0, ZOrder::BACKGROUND) @boxes.each { |box| box.draw } end end # The falling boxes class. # Nothing more than a body and an image. class Box def initialize(image, body) @image = image @body = body end # If it goes offscreen we put it back to the top. def check_off_screen pos = @body.p if pos.y > HEIGHT + EDGE_SIZE or pos.x > WIDTH + EDGE_SIZE or pos.x < -EDGE_SIZE @body.p = CP::Vec2.new(rand * WIDTH, 0) end end def draw @image.draw_rot(@body.p.x, @body.p.y, ZOrder::BOX, @body.a.radians_to_gosu) end end ChipmunkAndRMagick.new.show if __FILE__ == $0
gosu
サンプル
Gosu + RMagick.
require 'bundler/setup' require 'gosu' require 'rmagick' class GameWindow < Gosu::Window def initialize super 640, 480, false self.caption = "Gosu" fill = Magick::TextureFill.new(Magick::ImageList.new("plasma:fractal") {self.size = '640x480'}) background = Magick::Image.new(640, 480, fill) @background_image = Gosu::Image.new(background) end def update end def draw @background_image.draw(0, 0, 0) end end window = GameWindow.new window.show
円の表示。
require 'bundler/setup' require 'gosu' require 'rmagick' class MyWindow < Gosu::Window def initialize super 400, 300, false self.caption = "Gosu" background = Magick::Image.new(400, 300) {self.background_color = "gray"} @background_image = Gosu::Image.new(background) circle_image = Magick::Image.new(61, 61) {self.background_color = 'transparent'} gc = Magick::Draw.new gc.fill('cyan') gc.circle(30, 30, 0, 30) gc.draw(circle_image) @circle = Gosu::Image.new(circle_image) end def update end def draw @background_image.draw(0, 0, 0) @circle.draw(100, 100, 1) @circle.draw(300, 200, 1) end end window = MyWindow.new window.show
アニメーションにする。描画はデフォルトで1/60秒毎。
class MyWindow < Gosu::Window def initialize ... @x = 100 end def draw @background_image.draw(0, 0, 0) @circle.draw_rot(@x, 150, 1, 0) @x += 1 @x = 100 if @x > 300 end end
Chipmunk を導入。黄色い円が落ちていきます。下リンク先を参考にした。
Chipmunkのエッセンス - mirichiの日記
require 'bundler/setup' require 'gosu' require 'rmagick' require 'chipmunk' Width, Height = 300, 600 class MyWindow < Gosu::Window def initialize super Width, Height, false self.caption = "Gosu + Chipmunk" background = Magick::Image.new(Width, Height) {self.background_color = "gray"} @background_image = Gosu::Image.new(background) circle_image = Magick::Image.new(61, 61) {self.background_color = 'transparent'} gc = Magick::Draw.new gc.fill('yellow') gc.circle(30, 30, 0, 30) gc.draw(circle_image) @circle = Gosu::Image.new(circle_image) #chipmunk設定 @space = CP::Space.new @space.gravity = CP::Vec2.new(0, 100) @body = CP::Body.new(CP::INFINITY, CP::INFINITY) @body.p = CP::Vec2.new(150, 100) shape = CP::Shape::Circle.new(@body, 30, CP::Vec2.new(0, 0)) @space.add_body(@body) @space.add_shape(shape) end def update @space.step(1.0 / 60) end def draw @background_image.draw(0, 0, 0) @circle.draw_rot(@body.p.x, @body.p.y, 1, 0) end end window = MyWindow.new window.show
黄色い球が地面で跳ね返る。
gosu_chipmunk_sample1.rb
require 'bundler/setup' require 'gosu' require 'rmagick' require 'chipmunk' Width, Height = 300, 600 Wall_h = 20 class MyWindow < Gosu::Window def initialize super Width, Height, false self.caption = "Gosu + Chipmunk" background = Magick::Image.new(Width, Height) {self.background_color = "gray"} @background_image = Gosu::Image.new(background) circle_image = Magick::Image.new(61, 61) {self.background_color = 'transparent'} gc = Magick::Draw.new gc.fill('yellow') gc.circle(30, 30, 0, 30) gc.draw(circle_image) @circle = Gosu::Image.new(circle_image) wall_image = Magick::Image.new(Width, Height) gc = Magick::Draw.new gc.fill('firebrick') gc.rectangle(0, 0, Width, Wall_h) gc.draw(wall_image) @wall = Gosu::Image.new(wall_image) #chipmunk設定 #球 @space = CP::Space.new @space.gravity = CP::Vec2.new(0, 100) @body = CP::Body.new(1, CP::INFINITY) @body.p = CP::Vec2.new(150, 100) shape = CP::Shape::Circle.new(@body, 30, CP::Vec2.new(0, 0)) shape.e = 0.8 shape.u = 1 @space.add_body(@body) @space.add_shape(shape) #地面 sb = CP::Body.new_static x1, y1 = 0, Height - Wall_h x2, y2 = Width, Height verts = [CP::Vec2.new(x1, y1), CP::Vec2.new(x1, y2), CP::Vec2.new(x2, y2), CP::Vec2.new(x2, y1)] wshape = CP::Shape::Poly.new(sb, verts, CP::Vec2.new(0, 0)) wshape.e = 1 wshape.u = 1 @space.add_shape(wshape) end def update @space.step(1.0 / 60) end def draw @background_image.draw(0, 0, 0) @circle.draw_rot(@body.p.x, @body.p.y, 2, 0) @wall.draw(0, Height - Wall_h, 1) end end window = MyWindow.new window.show
わーい、できた。
さらなる情報
回転がよくわからない。
ruby and chipmunk
Ruby Chipmunk Integration beginner hacking gosu-example
https://github.com/gosu/gosu-examples/blob/master/examples/chipmunk_integration.rb
https://github.com/PhilCK/Chipmunk-Examples/blob/master/02_slides.rb
https://github.com/Sylvain303/gosu-examples/blob/test_chipmunk/examples/chipmunk_integration.rb#L218