Skip to content

Commit a5b7576

Browse files
author
monkstone
committed
mergefix
1 parent 8e4c09b commit a5b7576

File tree

2 files changed

+145
-17
lines changed

2 files changed

+145
-17
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
require 'pbox2d'
2+
3+
class CustomShape
4+
include Processing::Proxy
5+
# We need to keep track of a Body and a width and height
6+
attr_reader :body, :box2d
7+
8+
# Constructor
9+
def initialize(b2d, x, y)
10+
# Add the box to the box2d world
11+
@box2d = b2d
12+
make_body(Vec2.new(x, y))
13+
end
14+
15+
# This function removes the particle from the box2d world
16+
def kill_body!
17+
box2d.destroy_body(body)
18+
true
19+
end
20+
21+
# Is the particle ready for deletion?
22+
def done?
23+
# Let's find the screen position of the particle
24+
pos = box2d.body_coord(body)
25+
# Is it off the bottom of the screen?
26+
return false unless pos.y > box2d.height
27+
kill_body!
28+
end
29+
30+
# Drawing the box
31+
def display
32+
# We look at each body and get its screen position
33+
pos = box2d.body_coord(body)
34+
# Get its angle of rotation
35+
a = body.get_angle
36+
f = body.get_fixture_list
37+
ps = f.get_shape
38+
rect_mode(CENTER)
39+
push_matrix
40+
translate(pos.x, pos.y)
41+
rotate(-a)
42+
fill(175)
43+
stroke(0)
44+
begin_shape
45+
# For every vertex, convert to pixel vector
46+
ps.get_vertex_count.times do |i|
47+
v = box2d.vector_to_processing(ps.get_vertex(i))
48+
vertex(v.x, v.y)
49+
end
50+
end_shape(CLOSE)
51+
pop_matrix
52+
end
53+
54+
# This function adds the rectangle to the box2d world
55+
def make_body(center)
56+
# Define a polygon (this is what we use for a rectangle)
57+
sd = PolygonShape.new
58+
vertices = []
59+
vertices << box2d.vector_to_world(Vec2.new(-15, 25))
60+
vertices << box2d.vector_to_world(Vec2.new(15, 0))
61+
vertices << box2d.vector_to_world(Vec2.new(20, -15))
62+
vertices << box2d.vector_to_world(Vec2.new(-10, -10))
63+
sd.set(vertices.to_java(Java::OrgJbox2dCommon::Vec2), vertices.length)
64+
# Define the body and make it from the shape
65+
bd = BodyDef.new
66+
bd.type = BodyType::DYNAMIC
67+
bd.position.set(box2d.processing_to_world(center))
68+
@body = box2d.create_body(bd)
69+
body.create_fixture(sd, 1.0)
70+
# Give it some initial random velocity
71+
body.set_linear_velocity(Vec2.new(rand(-5.0..5), rand(2.0..5)))
72+
body.set_angular_velocity(rand(-5.0..5))
73+
end
74+
end
75+
76+
class Boundary
77+
include Processing::Proxy
78+
attr_reader :box2d, :b, :x, :y, :w, :h
79+
def initialize(b2d, x, y, w, h, a)
80+
@box2d, @x, @y, @w, @h = b2d, x, y, w, h
81+
# Define the polygon
82+
sd = PolygonShape.new
83+
# Figure out the box2d coordinates
84+
box2d_w = box2d.scale_to_world(w / 2)
85+
box2d_h = box2d.scale_to_world(h / 2)
86+
# We're just a box
87+
sd.set_as_box(box2d_w, box2d_h)
88+
# Create the body
89+
bd = BodyDef.new
90+
bd.type = BodyType::STATIC
91+
bd.angle = a
92+
bd.position.set(box2d.processing_to_world(x, y))
93+
@b = box2d.create_body(bd)
94+
# Attached the shape to the body using a Fixture
95+
b.create_fixture(sd, 1)
96+
end
97+
98+
# Draw the boundary, it doesn't move so we don't have to ask
99+
# the Body for location
100+
def display
101+
fill(0)
102+
stroke(0)
103+
stroke_weight(1)
104+
rect_mode(CENTER)
105+
a = b.get_angle
106+
push_matrix
107+
translate(x, y)
108+
rotate(-a)
109+
rect(0, 0, w, h)
110+
pop_matrix
111+
end
112+
end
113+
114+
module Runnable
115+
def run
116+
reject! { |item| item.done? }
117+
each { |item| item.display }
118+
end
119+
end
120+
121+
class ParticleSystem
122+
include Enumerable, Runnable
123+
extend Forwardable
124+
attr_reader :particles
125+
126+
def_delegators(:@particles, :each, :reject!, :<<)
127+
128+
def initialize
129+
@particles = []
130+
end
131+
132+
def add_shape(b2d, x, y)
133+
@particles << CustomShape.new(b2d, x, y)
134+
end
135+
end

samples/external_library/ruby_gem/jbox2d/polygons.rb

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,31 @@
22
require 'pbox2d'
33
require_relative 'lib/custom_shape'
44

5-
attr_reader :box2d, :boundaries, :polygons
5+
attr_reader :box2d, :boundaries, :system
66

77
def setup
88
size(640, 360)
99
smooth
10-
# Initialize box2d physics and create the world
1110
@box2d = Box2D.new(self)
1211
box2d.init_options(gravity: [0, -20])
1312
box2d.create_world
14-
# To later set a custom gravity
15-
# box2d.gravity([0, -20]
16-
# Create Arrays
17-
@polygons = []
18-
@boundaries = []
19-
# Add a bunch of fixed boundaries
20-
boundaries << Boundary.new(self, width / 4, height - 5, width / 2 - 50, 10, 0)
21-
boundaries << Boundary.new(self, 3 * width / 4, height - 50, width / 2 - 50, 10, 0)
22-
boundaries << Boundary.new(self, width - 5, height / 2, 10, height, 0)
23-
boundaries << Boundary.new(self, 5, height / 2, 10, height, 0)
13+
@system = ParticleSystem.new
14+
@boundaries = [
15+
Boundary.new(box2d, width / 4, height - 5, width / 2 - 50, 10, 0),
16+
Boundary.new(box2d, 3 * width / 4, height - 50, width / 2 - 50, 10, 0),
17+
Boundary.new(box2d, width - 5, height / 2, 10, height, 0),
18+
Boundary.new(box2d, 5, height / 2, 10, height, 0)
19+
]
2420
end
2521

2622
def draw
2723
background(255)
2824
# Display all the boundaries
2925
boundaries.each(&:display)
3026
# Display all the polygons
31-
polygons.each(&:display)
32-
# polygons that leave the screen, we delete them
33-
# (note they have to be deleted from both the box2d world and our list
34-
polygons.reject!(&:done)
27+
system.run
3528
end
3629

3730
def mouse_pressed
38-
polygons << CustomShape.new(self, mouse_x, mouse_y)
31+
system << CustomShape.new(box2d, mouse_x, mouse_y)
3932
end

0 commit comments

Comments
 (0)