Skip to content

Commit f316f9e

Browse files
author
monkstone
committed
various
1 parent d724337 commit f316f9e

6 files changed

Lines changed: 170 additions & 214 deletions

File tree

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,42 @@
11
# The Nature of Code
2-
# <http://www.shiffman.net/teaching/nature>
3-
# Spring 2010
4-
# PBox2D example
5-
2+
# PBox2D example translated to use pbox2d gem by Martin Prout, and to use
3+
# forwardable instead of Processing::Proxy to mimic java inner class access
64
# An uneven surface
75

8-
load_libraries :box2d_processing, :surface
9-
10-
include SB
6+
require 'pbox2d'
7+
load_library :surface
118

129
attr_reader :surface, :box2d, :particles
1310

1411
def setup
15-
size(500,300)
16-
smooth
17-
12+
size(500, 300)
13+
smooth 4
1814
# Initialize box2d physics and create the world
19-
@box2d = SB::Box2DProcessing.new(self)
15+
@box2d = Box2D.new(self)
16+
box2d.init_options(gravity: [0, -20])
2017
box2d.create_world
21-
# We are setting a custom gravity
22-
box2d.set_gravity(0, -20)
23-
18+
# to later set a custom gravity
19+
# box2d.gravity([0, -20])
2420
# Create the empty list
2521
@particles = []
2622
# Create the surface
27-
@surface = Surface.new(box2d)
23+
@surface = Surface.new(self)
2824
end
2925

3026
def draw
3127
# If the mouse is pressed, we make new particles
32-
33-
3428
# We must always step through time!
35-
box2d.step
36-
37-
background(138, 66, 54)
29+
background(138, 66, 54)
3830
# Draw the surface
3931
surface.display
40-
# NB question mark is reqd to call mouse_pressed value, else method gets called.
41-
particles << Particle.new(box2d, mouse_x, mouse_y, rand(2.0..6)) if mouse_pressed?
32+
# NB ? reqd to call mouse_pressed value, else method gets called.
33+
particles << Particle.new(self, mouse_x, mouse_y, rand(2.0..6)) if mouse_pressed?
4234
# Draw all particles
43-
particles.each do |p|
44-
p.display
45-
end
35+
particles.each(&:display)
4636
# Particles that leave the screen, we delete them
4737
# (note they have to be deleted from both the box2d world and our list
48-
particles.reject! {|p| p.done}
38+
particles.reject!(&:done)
4939
# Just drawing the framerate to see how many particles it can handle
5040
fill(0)
51-
text("framerate: #{frame_rate.to_i}", 12, 16)
41+
text(format('framerate: %d', frame_rate.to_i), 12, 16)
5242
end
Lines changed: 129 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,136 @@
1+
require 'forwardable'
2+
13
# The Nature of Code
2-
# <http://www.shiffman.net/teaching/nature>
3-
# Spring 2010
44
# PBox2D example
5-
65
# An uneven surface boundary
7-
module SB
8-
9-
include_package 'org.jbox2d.collision.shapes'
10-
include_package 'org.jbox2d.common'
11-
include_package 'org.jbox2d.dynamics'
12-
include_package 'shiffman.box2d'
13-
14-
15-
16-
class Surface
17-
# We'll keep track of all of the surface points
18-
attr_reader :surface, :body, :box2d, :y, :width, :height
19-
20-
21-
def initialize b2d
22-
@box2d = b2d
23-
@surface = []
24-
@width, @height = $app.width, $app.height
25-
# This is what box2d uses to put the surface in its world
26-
chain = SB::ChainShape.new
27-
28-
# Perlin noise argument
29-
xoff = 0.0
30-
31-
# This has to go backwards so that the objects bounce off the top of the surface
32-
# This "edgechain" will only work in one direction!
33-
(width + 10).step(-10, -5) do |x|
34-
# Doing some stuff with perlin noise to calculate a surface that points down on one side
35-
# and up on the other
36-
37-
if (x > width/2)
38-
@y = 100 + (width - x)*1.1 + map(noise(xoff),0,1,-80,80)
39-
else
40-
@y = 100 + x*1.1 + map(noise(xoff),0,1,-80,80)
41-
end
42-
43-
# Store the vertex in screen coordinates
44-
surface << SB::Vec2.new(x, y)
45-
46-
# Move through perlin noise
47-
xoff += 0.1
48-
49-
end
50-
51-
# Build an array of vertices in Box2D coordinates
52-
# from the ArrayList we made
53-
vertices = []
54-
surface.each do |surf|
55-
vertices << box2d.coord_pixels_to_world(surf)
56-
end
57-
# Create the chain!
58-
chain.createChain(vertices, vertices.length)
59-
# The edge chain is now attached to a body via a fixture
60-
bd = SB::BodyDef.new
61-
bd.position.set(0.0, 0.0)
62-
@body = box2d.createBody(bd)
63-
# Shortcut, we could define a fixture if we
64-
# want to specify frictions, restitution, etc.
65-
body.createFixture(chain, 1)
66-
end
67-
68-
# A simple function to just draw the edge chain as a series of vertex points
69-
def display
70-
stroke_weight(2)
71-
stroke(0)
72-
fill(135, 206, 250)
73-
beginShape
74-
vertex(width, 0) # extra vertices so we can fill sky
75-
surface.each do |v|
76-
vertex(v.x, v.y) # the mountain range
77-
end
78-
vertex(0, 0) # extra vertices so we can fill sky
79-
endShape
80-
end
81-
end
82-
83-
class Particle
84-
# We need to keep track of a Body
85-
86-
attr_reader :body, :box2d, :x, :y, :r
87-
88-
# Constructor
89-
def initialize(b2d, x, y, r)
90-
@box2d, @x, @y, @r = b2d, x, y, r
91-
# This function puts the particle in the Box2d world
92-
make_body(x, y, r)
93-
end
94-
95-
# This function removes the particle from the box2d world
96-
def kill_body
97-
box2d.destroy_body(body)
98-
end
99-
100-
# Is the particle ready for deletion?
101-
def done
102-
pos = box2d.get_body_pixel_coord(body)
103-
# Is it off the bottom of the screen?
104-
if (pos.y > $app.height + r * 2)
105-
kill_body
106-
return true
6+
class Surface
7+
extend Forwardable
8+
# We'll keep track of all of the surface points
9+
def_delegators(:@app, :box2d, :width, :height, :begin_shape,
10+
:end_shape, :fill, :stroke, :stroke_weight,
11+
:vertex, :map1d, :noise)
12+
attr_reader :surface, :body, :y
13+
14+
def initialize(app)
15+
@app = app
16+
@surface = []
17+
# This is what box2d uses to put the surface in its world
18+
chain = ChainShape.new
19+
# Perlin noise argument
20+
xoff = 0.0
21+
# This has to go backwards so that the objects bounce off the top of the
22+
# surface. This "edgechain" will only work in one direction!
23+
(width + 10).step(-10, -5) do |x|
24+
# Doing some stuff with perlin noise to calculate a surface that points
25+
# down on one side and up on the other
26+
if x > width / 2
27+
@y = 100 + (width - x) * 1.1 + map1d(noise(xoff), (0..1.0), (-80..80))
28+
else
29+
@y = 100 + x * 1.1 + map1d(noise(xoff), (0..1.0), (-80..80))
10730
end
108-
return false
31+
# Store the vertex in screen coordinates
32+
surface << Vec2.new(x, y)
33+
# Move through perlin noise
34+
xoff += 0.1
10935
end
110-
111-
def display
112-
# We look at each body and get its screen position
113-
pos = box2d.get_body_pixel_coord(body)
114-
# Get its angle of rotation
115-
a = body.get_angle
116-
push_matrix
117-
translate(pos.x, pos.y)
118-
rotate(-a)
119-
fill(175)
120-
stroke(0)
121-
stroke_weight(1)
122-
ellipse(0,0,r*2,r*2)
123-
# Let's add a line so we can see the rotation
124-
line(0,0,r,0)
125-
pop_matrix
36+
# Build an array of vertices in Box2D coordinates
37+
# from the ArrayList we made
38+
vertices = []
39+
surface.each do |surf|
40+
vertices << box2d.processing_to_world(surf)
12641
end
127-
128-
# This function adds the rectangle to the box2d world
129-
def make_body(x, y, r)
130-
# Define and create the body
131-
bd = SB::BodyDef.new
132-
bd.position = box2d.coord_pixels_to_world(x,y)
133-
bd.type = SB::BodyType::DYNAMIC
134-
@body = box2d.world.create_body(bd)
135-
# Make the body's shape a circle
136-
cs = SB::CircleShape.new
137-
cs.m_radius = box2d.scalar_pixels_to_world(r)
138-
fd = SB::FixtureDef.new
139-
fd.shape = cs
140-
# Parameters that affect physics
141-
fd.density = 1
142-
fd.friction = 0.01
143-
fd.restitution = 0.3
144-
# Attach fixture to body
145-
body.create_fixture(fd)
146-
# Give it a random initial velocity (and angular velocity)
147-
body.set_linear_velocity(SB::Vec2.new(rand(-10..10), rand(5..10)))
148-
body.set_angular_velocity(rand(-10..10))
149-
end
150-
end
151-
end
152-
153-
42+
# Create the chain!
43+
chain.createChain(vertices, vertices.length)
44+
# The edge chain is now attached to a body via a fixture
45+
bd = BodyDef.new
46+
bd.position.set(0.0, 0.0)
47+
@body = box2d.createBody(bd)
48+
# Shortcut, we could define a fixture if we
49+
# want to specify frictions, restitution, etc.
50+
body.createFixture(chain, 1)
51+
end
52+
53+
# A simple function to just draw the edge chain as a series of vertex points
54+
def display
55+
stroke_weight(2)
56+
stroke(0)
57+
fill(135, 206, 250)
58+
begin_shape
59+
vertex(width, 0) # extra vertices so we can fill sky
60+
surface.map { |v| vertex(v.x, v.y) } # the mountain range
61+
vertex(0, 0) # extra vertices so we can fill sky
62+
end_shape
63+
end
64+
end
15465

66+
# Using forwardable again
67+
class Particle
68+
extend Forwardable
69+
def_delegators(:@app, :box2d, :push_matrix, :pop_matrix, :rotate,
70+
:translate, :fill, :stroke, :stroke_weight, :noise,
71+
:map1d, :ellipse, :line)
72+
# We need to keep track of a Body
73+
74+
attr_reader :body, :x, :y, :r
75+
76+
# Constructor
77+
def initialize(app, x, y, r)
78+
@app, @x, @y, @r = app, x, y, r
79+
# This function puts the particle in the Box2d world
80+
make_body(x, y, r)
81+
end
82+
83+
# This function removes the particle from the box2d world
84+
def kill_body
85+
box2d.destroy_body(body)
86+
end
87+
88+
# Is the particle ready for deletion?
89+
def done
90+
pos = box2d.body_coord(body)
91+
# Is it off the bottom of the screen?
92+
return false unless pos.y > box2d.height + r * 2
93+
kill_body
94+
true
95+
end
96+
97+
def display
98+
# We look at each body and get its screen position
99+
pos = box2d.body_coord(body)
100+
# Get its angle of rotation
101+
a = body.get_angle
102+
push_matrix
103+
translate(pos.x, pos.y)
104+
rotate(-a)
105+
fill(175)
106+
stroke(0)
107+
stroke_weight(1)
108+
ellipse(0, 0, r * 2, r * 2)
109+
# Let's add a line so we can see the rotation
110+
line(0, 0, r, 0)
111+
pop_matrix
112+
end
113+
114+
# This function adds the rectangle to the box2d world
115+
def make_body(x, y, r)
116+
# Define and create the body
117+
bd = BodyDef.new
118+
bd.position = box2d.processing_to_world(x, y)
119+
bd.type = BodyType::DYNAMIC
120+
@body = box2d.create_body(bd)
121+
# Make the body's shape a circle
122+
cs = CircleShape.new
123+
cs.m_radius = box2d.scale_to_world(r)
124+
fd = FixtureDef.new
125+
fd.shape = cs
126+
# Parameters that affect physics
127+
fd.density = 1
128+
fd.friction = 0.01
129+
fd.restitution = 0.3
130+
# Attach fixture to body
131+
body.create_fixture(fd)
132+
# Give it a random initial velocity (and angular velocity)
133+
body.set_linear_velocity(Vec2.new(rand(-10..10), rand(5..10)))
134+
body.set_angular_velocity(rand(-10..10))
135+
end
136+
end

samples/external_library/java_processing/box2d_processing/polygons.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
attr_reader :box2d, :boundaries, :polygons
1313

1414
def setup
15-
size(640,360)
15+
size(640, 360)
1616
smooth
1717
# Initialize box2d physics and create the world
1818
@box2d = B2D::Box2DProcessing.new(self)

0 commit comments

Comments
 (0)