Things are little bit more complicated for JRubyArt (compared with ruby-processing) as I am currently refusing to use the Processing::Proxy sugar (that allows you in part to mimic the inner classes of vanilla processing) in JRubyArt as it is kind of bad practice to expose variables and methods willy nilly.
require 'jruby_art'
require 'pbox2d'
require_relative 'lib/custom_shape'
class Polygons < Processing::App
attr_reader :box2d, :boundaries, :polygons
def setup
size(640, 360)
@box2d = Box2D.new(self)
box2d.create_world
box2d.gravity(0, -20)
@polygons = []
@boundaries = []
boundaries << Boundary.new(box2d, width / 4, height - 5, width / 2 - 50, 10, 0)
boundaries << Boundary.new(box2d, 3 * width / 4, height - 50, width / 2 - 50, 10, 0)
boundaries << Boundary.new(box2d, width - 5, height / 2, 10, height, 0)
boundaries << Boundary.new(box2d, 5, height / 2, 10, height, 0)
end
def draw
background(255)
boundaries.each { |wall| wall.display(self) }
polygons.each { |poly| poly.display(self) }
polygons.reject!(&:done)
end
def mouse_pressed
polygons << CustomShape.new(box2d, mouse_x, mouse_y, height)
end
end
Polygons.new(title: 'Polygons')
CLOSE = Java::ProcessingCore::PConstants::CLOSE
CENTER = Java::ProcessingCore::PConstants::CENTER
class CustomShape
include PB
attr_reader :body, :box2d, :height
def initialize(b2d, x, y, height)
@box2d, @height = b2d, height
make_body(PB::Vec2.new(x, y))
end
def kill_body!
box2d.destroy_body(body)
end
def done
pos = box2d.body_coord(body)
return false unless pos.y > height
kill_body!
true
end
def display(app)
pos = box2d.body_coord(body)
a = body.get_angle
f = body.get_fixture_list
ps = f.get_shape
app.rect_mode(CENTER)
app.push_matrix
app.translate(pos.x, pos.y)
app.rotate(-a)
app.fill(175)
app.stroke(0)
app.begin_shape
ps.get_vertex_count.times do |i|
v = box2d.vector_to_processing(ps.get_vertex(i))
app.vertex(v.x, v.y)
end
app.end_shape(CLOSE)
app.pop_matrix
end
def make_body(center)
sd = PB::PolygonShape.new
vertices = []
vertices << box2d.vector_to_world(PB::Vec2.new(-15, 25))
vertices << box2d.vector_to_world(PB::Vec2.new(15, 0))
vertices << box2d.vector_to_world(PB::Vec2.new(20, -15))
vertices << box2d.vector_to_world(PB::Vec2.new(-10, -10))
sd.set(vertices.to_java(Java::OrgJbox2dCommon::Vec2), vertices.length)
bd = PB::BodyDef.new
bd.type = PB::BodyType::DYNAMIC
bd.position.set(box2d.processing_to_world(center))
@body = box2d.create_body(bd)
body.create_fixture(sd, 1.0)
body.set_linear_velocity(Vec2.new(rand(-5.0..5), rand(2.0..5)))
body.set_angular_velocity(rand(-5.0..5))
end
end
class Boundary
include PB
attr_reader :box2d, :b, :x, :y, :w, :h
def initialize(b2d, x, y, w, h, a)
@box2d, @x, @y, @w, @h = b2d, x, y, w, h
sd = PB::PolygonShape.new
box2d_w = box2d.scale_to_world(w / 2)
box2d_h = box2d.scale_to_world(h / 2)
sd.set_as_box(box2d_w, box2d_h)
bd = PB::BodyDef.new
bd.type = PB::BodyType::STATIC
bd.angle = a
bd.position.set(box2d.processing_to_world(x, y))
@b = box2d.create_body(bd)
b.create_fixture(sd, 1)
end
def display(app)
app.fill(0)
app.stroke(0)
app.stroke_weight(1)
app.rect_mode(CENTER)
a = b.get_angle
app.push_matrix
app.translate(x, y)
app.rotate(-a)
app.rect(0, 0, w, h)
app.pop_matrix
end
end
No comments:
Post a Comment