再びBox2D

丸い形状も扱えるようになった。

Box2DのオブジェクトとDXRubyのImageをカプセル化してみた。

require 'rubygems'
require 'dxruby'
require 'box2d'

include Box2d

b = B2AABB.new
b.minVertex.set(0.0, 0.0) # 世界の左上
b.maxVertex.set(640.0, 480.0) # 世界の右下
gravity = B2Vec2.new(0, 100.0) # 重力
$world = B2World.new(b, gravity, true) # 世界作成

# 四角
class Box
  def initialize(x, y, width, height, density = 1.0, friction = 0.3, restitution = 0.5)
    @width = width
    @height = height
    boxDef = B2BoxDef.new
    boxDef.extents.set(width/2, height/2)
    boxDef.density = density # 密度・・??とりあえず0にすると落ちない
    boxDef.friction = friction # 摩擦
    boxDef.restitution = restitution # 反発係数。これらは0.0〜1.0で設定する
    bodyDef = B2BodyDef.new
    bodyDef.position.set(x + width/2, y + height/2)
    bodyDef.add_shape(boxDef)
    @body = $world.create_body(bodyDef)
    @image = Image.new(width, height).box(0, 0, width-1, height-1, [255,255,255])
  end

  def draw
    pos = @body.get_origin_position()
    rot = @body.get_rotation()
    Window.drawRot(pos.x-@width/2, pos.y-@height/2, @image, rot / Math::PI * 180)
  end
end

# 丸
class Circle
  def initialize(x, y, r, density = 1.0, friction = 0.0, restitution = 0.5)
    @r = r
    circleDef = B2CircleDef.new
    circleDef.radius = r
    circleDef.density = density # 密度・・??とりあえず0にすると落ちない
    circleDef.friction = friction # 摩擦
    circleDef.restitution = restitution # 反発係数。これらは0.0〜1.0で設定する
    bodyDef = B2BodyDef.new
    bodyDef.position.set(x + r, y + r)
    bodyDef.add_shape(circleDef)
    @body = $world.create_body(bodyDef)
    @image = Image.new(r*2-1, r*2-1).circle(r-1, r-1, r-1, [255,255,255])
  end

  def draw
    pos = @body.get_origin_position()
    rot = @body.get_rotation()
    Window.draw(pos.x-@r+1, pos.y-@r+1, @image)
  end
end

# 四角作成
body = Array.new(20) do
  Box.new(rand(520)+40,rand(300), 30, 60)
end

# 丸追加
body += Array.new(20) do
  Circle.new(rand(480)+40,rand(300), 30)
end

# 枠作成
body.push Box.new(0, 440, 640, 40, 0)
body.push Box.new(0, 0, 40, 440, 0)
body.push Box.new(600, 0, 40, 440, 0)

timeStep = 1.0 / 60.0
iterations = 10
Window.loop do
  # 世界を動かす
  $world.step(timeStep, iterations)

  # 描画
  body.each do |b|
    b.draw
  end

  break if Input.keyPush?(K_ESCAPE)
end