load_library :pbox2d
load_library :surface
include SB
attr_reader :surface, :box2d, :particles
def setup
size(500,300)
smooth
@box2d = PBox2D.new(self)
box2d.create_world
box2d.set_gravity(0, -20)
@particles = []
@surface = Surface.new(box2d)
end
def draw
box2d.step
background(138, 66, 54)
surface.display
particles << Particle.new(box2d, mouse_x, mouse_y, rand(2.0 .. 6)) if mouse_pressed?
particles.each do |p|
p.display
end
particles.each_with_index do |p, i|
if (p.done)
particles.delete_at(i)
end
end
fill(0)
text("framerate: #{frame_rate.to_i}", 12, 16)
end
The library module, which encapsulates the import of classes, and additional classes for surface and particles.
module SB
include_package 'org.jbox2d.collision.shapes'
include_package 'org.jbox2d.common'
include_package 'org.jbox2d.dynamics'
java_import 'pbox2d.PBox2D'
class Surface
attr_reader :surface, :body, :box2d, :y, :width, :height
def initialize b2d
@box2d = b2d
@surface = []
@width, @height = $app.width, $app.height
chain = SB::ChainShape.new
xoff = 0.0
(width + 10).step(-10, -5) do |x|
if (x > width/2)
@y = 100 + (width - x)*1.1 + map(noise(xoff),0,1,-80,80)
else
@y = 100 + x*1.1 + map(noise(xoff),0,1,-80,80)
end
surface << SB::Vec2.new(x, y)
xoff += 0.1
end
vertices = []
surface.each do |surf|
vertices << box2d.coord_pixels_to_world(surf)
end
chain.createChain(vertices, vertices.length)
bd = SB::BodyDef.new
bd.position.set(0.0, 0.0)
@body = box2d.createBody(bd)
body.createFixture(chain, 1)
end
def display
stroke_weight(2)
stroke(0)
fill(135, 206, 250)
beginShape
vertex(width, 0)
surface.each do |v|
vertex(v.x, v.y)
end
vertex(0, 0)
endShape
end
end
class Particle
attr_reader :body, :box2d, :x, :y, :r
def initialize(b2d, x, y, r)
@box2d, @x, @y, @r = b2d, x, y, r
make_body(x, y, r)
end
def kill_body
box2d.destroy_body(body)
end
def done
pos = box2d.get_body_pixel_coord(body)
if (pos.y > $app.height + r * 2)
kill_body
return true
end
return false
end
def display
pos = box2d.get_body_pixel_coord(body)
a = body.get_angle
push_matrix
translate(pos.x, pos.y)
rotate(-a)
fill(175)
stroke(0)
stroke_weight(1)
ellipse(0,0,r*2,r*2)
line(0,0,r,0)
pop_matrix
end
def make_body(x, y, r)
bd = SB::BodyDef.new
bd.position = box2d.coord_pixels_to_world(x,y)
bd.type = SB::BodyType::DYNAMIC
@body = box2d.world.create_body(bd)
cs = SB::CircleShape.new
cs.m_radius = box2d.scalar_pixels_to_world(r)
fd = SB::FixtureDef.new
fd.shape = cs
fd.density = 1
fd.friction = 0.01
fd.restitution = 0.3
body.create_fixture(fd)
body.set_linear_velocity(SB::Vec2.new(rand(-10 .. 10), rand(5 .. 10)))
body.set_angular_velocity(rand(-10 .. 10))
end
end
end