and here a working sample (with gosu): (the media files are missed)
Code:
require 'rubygems'
require 'gosu'
require 'box2d'
include Box2d
class GameWindow < Gosu::Window
RadToDeg = 57.295779513082323
def initialize
super(640,480, false, 20)
self.caption = "Box2d Demo"
# Pointer ist 28x38, Hotspot 6,1
@pointer = Gosu::Image.new(self, "media/img/pointer.png", true)
@stone = Gosu::Image.new(self, "media/img/stone.png", false)
@info = Gosu::Font.new(self, "arial", 12)
b = B2AABB.new
b.minVertex.set(0.0, 0.0)
b.maxVertex.set(640.0, 480.0)
gravity = B2Vec2.new(0.0, 180.0)
do_sleep = true
@w = B2World.new(b,gravity,do_sleep)
groundBoxDef = B2BoxDef.new
groundBoxDef.extents.set(320.0, 5.0)
groundBoxDef.density = 0.0
groundBodyDef = B2BodyDef.new
groundBodyDef.position.set(320.0, 460.0)
groundBodyDef.add_shape(groundBoxDef)
@walls = []
bd = create_wall(320.0,5.0,320.0,460.0)
@walls << {:body => @w.create_body(bd), :shape => [320.0,5.0]};
bd = create_wall(5.0,130.0,5.0,325.0)
@walls << {:body => @w.create_body(bd), :shape => [5.0,130.0]};
bd = create_wall(5.0,130.0,635,325.0)
@walls << {:body => @w.create_body(bd), :shape => [5.0,130.0]};
bd = create_box(20.0,20.0,320.0,40.0,0.6)
@entities = []
@entities << {:body => @w.create_body(bd), :shape => [20.0,20.0]};
@last_time = Gosu::milliseconds()
end
def create_box(w,h,x,y,rot)
boxDef = B2BoxDef.new
boxDef.extents.set(w,h)
boxDef.density = 0.1
boxDef.friction = 1.3
boxDef.restitution = 0.5
bodyDef = B2BodyDef.new
bodyDef.position.set(x,y)
bodyDef.rotation = rot
bodyDef.allowSleep = true;
bodyDef.add_shape(boxDef);
bodyDef.userData = ["box",10.0,10.0]
return bodyDef;
end
def create_wall(w,h,x,y)
boxDef = B2BoxDef.new
boxDef.extents.set(w,h)
boxDef.density = 0.0
bodyDef = B2BodyDef.new
bodyDef.position.set(x,y)
bodyDef.allowSleep = true;
bodyDef.add_shape(boxDef);
bodyDef.userData = ["wall",10.0,10.0]
return bodyDef;
end
def button_down(id)
if id == Gosu::Button::MsRight then
bd = create_box(20.0,20.0,self.mouse_x, self.mouse_y,0.0)
@entities << {:body => @w.create_body(bd), :shape => [20.0,20.0]};
end
end
def update
end
def draw
#c = Gosu::Color.new(255,0,0,255)
c = Gosu::Color.new(255,255,255,255)
c1 = Gosu::Color.new(167,167,167,167)
#time_step = (Gosu::milliseconds() - @last_time) / 1000.0
time_step = 1.0 / 60
@last_time = Gosu::milliseconds()
iterations = 10
@w.step(time_step, iterations)
@entities.each{|e|
pos = e[:body].get_origin_position()
rot = e[:body].get_rotation()
self.draw_stone(pos.x - e[:shape][0],pos.y - e[:shape][1], e[:shape][0] * 2, e[:shape][1] * 2,rot,c)
}
@walls.each{|w|
pos = w[:body].get_origin_position()
rot = w[:body].get_rotation()
self.draw_rectangle(pos.x - w[:shape][0],pos.y - w[:shape][1], w[:shape][0] * 2, w[:shape][1] * 2,rot,c1)
}
@info.draw("x: #{mouse_x} y: #{mouse_y} ms: #{time_step}",10,10,0)
@pointer.draw(self.mouse_x-6, self.mouse_y-1,0)
end
def draw_stone(x, y, w, h, rot,c)
if rot == 0.0
lt = [ x, y ]
lb = [ lt[0], lt[1] + h ]
rb = [ lt[0] + w, lt[1] + h ]
rt = [ lt[0] + w, lt[1] ]
@stone.draw_as_quad(lt[0], lt[1], c, lb[0], lb[1], c, rt[0], rt[1], c, rb[0], rb[1], c,-1.0)
else
pos = [x+(w/2.0),y+(h/2.0)]
lt = move(rotate([-w/2.0,-h/2.0], rot), pos)
lb = move(rotate([-w/2.0,h/2.0], rot), pos)
rb = move(rotate([w/2.0,h/2.0], rot), pos)
rt = move(rotate([w/2.0,-h/2.0], rot), pos)
@stone.draw_as_quad(lt[0], lt[1], c, lb[0], lb[1], c, rt[0], rt[1], c, rb[0], rb[1], c,-1.0)
end
end
def draw_rectangle(x, y, w, h, rot, c)
if rot == 0.0
lt = [ x, y ]
lb = [ lt[0], lt[1] + h ]
rb = [ lt[0] + w, lt[1] + h ]
rt = [ lt[0] + w, lt[1] ]
self.draw_quad(lt[0], lt[1], c, lb[0], lb[1], c, rt[0], rt[1], c, rb[0], rb[1], c)
else
pos = [x+(w/2.0),y+(h/2.0)]
lt = move(rotate([-w/2.0,-h/2.0], rot), pos)
lb = move(rotate([-w/2.0,h/2.0], rot), pos)
rb = move(rotate([w/2.0,h/2.0], rot), pos)
rt = move(rotate([w/2.0,-h/2.0], rot), pos)
self.draw_quad(lt[0], lt[1], c, lb[0], lb[1], c, rt[0], rt[1], c, rb[0], rb[1], c)
end
end
def move(p,pos)
return [p[0] + pos[0], p[1] + pos[1]]
end
def rotate(p, theta)
# x' = cos(theta)*x - sin(theta)*y
# y' = sin(theta)*x + cos(theta)*y
ct = Math.cos(theta)
cs = Math.sin(theta)
return [ct *p[0] - cs *p[1],cs*p[0] + ct*p[1]]
end
end
window = GameWindow.new
window.show