Skip to content

Commit 47a4832

Browse files
committed
add blobby example
1 parent e186a3e commit 47a4832

4 files changed

Lines changed: 174 additions & 0 deletions

File tree

examples/blobby/blob.rb

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# The Nature of Code
2+
# <http://www.shiffman.net/teaching/nature>
3+
# Spring 2012
4+
# Box2DProcessing example
5+
6+
# A blob skeleton
7+
# Could be used to create blobbly characters a la Nokia Friends
8+
# http://postspectacular.com/work/nokia/friends/start
9+
10+
class Blob
11+
include Processing::Proxy
12+
# A list to keep track of all the points in our blob
13+
attr_reader :skeleton, :body_radius, :radius, :total_points
14+
# We should modify this constructor to receive arguments
15+
# So that we can make many different types of blobs
16+
17+
def initialize
18+
# Create the empty
19+
@skeleton = []
20+
# Let's make a volume of joints!
21+
cvjd = ConstantVolumeJointDef.new
22+
# Where and how big is the blob
23+
center = Vec2.new(width / 2, height / 2)
24+
@radius = 100
25+
@total_points = 20
26+
@body_radius = 12
27+
# Initialize all the points
28+
total_points.times do |i|
29+
# Look polar to cartesian coordinate transformation!
30+
theta = map1d(i, 0..total_points, 0..TWO_PI)
31+
x = center.x + radius * sin(theta)
32+
y = center.y + radius * cos(theta)
33+
# Make each individual body
34+
bd = BodyDef.new
35+
bd.type = BodyType::DYNAMIC
36+
bd.fixedRotation = true # no rotation!
37+
bd.position.set(box2d.processing_to_world(Vec2.new(x, y)))
38+
body = box2d.createBody(bd)
39+
# The body is a circle
40+
cs = CircleShape.new
41+
cs.m_radius = box2d.scale_to_world(body_radius)
42+
# Define a fixture
43+
fd = FixtureDef.new
44+
fd.shape = cs
45+
# For filtering out collisions
46+
#fd.filter.groupIndex = -2
47+
# Parameters that affect physics
48+
fd.density = 1
49+
# Finalize the body
50+
body.create_fixture(fd)
51+
# Add it to the volume
52+
cvjd.add_body(body)
53+
# Store our own copy for later rendering
54+
skeleton << body
55+
end
56+
# These parameters control how stiff vs. jiggly the blob is
57+
cvjd.frequencyHz = 10.0
58+
cvjd.dampingRatio = 1.0
59+
# Put the joint thing in our world!
60+
box2d.world.create_joint(cvjd)
61+
end
62+
63+
# Time to draw the blob!
64+
# Can you make it a cute character, a la
65+
# http://postspectacular.com/work/nokia/friends/start
66+
def display
67+
# Draw the outline
68+
begin_shape
69+
no_fill
70+
stroke(0)
71+
stroke_weight(1)
72+
skeleton.each do |b|
73+
pos = box2d.body_coord(b)
74+
vertex(pos.x, pos.y)
75+
end
76+
end_shape(CLOSE)
77+
# Draw the individual circles
78+
skeleton.each do |b|
79+
# We look at each body and get its screen position
80+
pos = box2d.body_coord(b)
81+
# Get its angle of rotation
82+
a = b.get_angle
83+
push_matrix
84+
translate(pos.x, pos.y)
85+
rotate(a)
86+
fill(175)
87+
stroke(0)
88+
stroke_weight(1)
89+
ellipse(0, 0, body_radius * 2, body_radius * 2)
90+
pop_matrix
91+
end
92+
end
93+
end

examples/blobby/blobby.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# The Nature of Code
2+
# <http:#www.shiffman.net/teaching/nature>
3+
# Spring 2012
4+
# Box2DProcessing example
5+
6+
# A blob skeleton
7+
# Could be used to create blobbly characters a la Nokia Friends
8+
# http://postspectacular.com/work/nokia/friends/start
9+
10+
# This seems to be broken with the Box2D 2.1.2 version I'm using
11+
12+
require 'pbox2d'
13+
require 'forwardable'
14+
require_relative 'boundary'
15+
require_relative 'blob'
16+
17+
attr_reader :boundaries, :blob, :box2d
18+
19+
def settings
20+
size(400, 300)
21+
end
22+
23+
def setup
24+
sketch_title 'Blobby'
25+
# Initialize box2d physics and create the world
26+
@box2d = WorldBuilder.build(app: self, gravity: [0, -20])
27+
box2d.create_world
28+
@boundaries = []
29+
boundaries << Boundary.new(box2d, Vec2D.new(width / 2, height - 5), Vec2D.new(width, 10))
30+
boundaries << Boundary.new(box2d, Vec2D.new(width / 2, 5), Vec2D.new(width, 10))
31+
boundaries << Boundary.new(box2d, Vec2D.new(width - 5, height / 2), Vec2D.new(10, height))
32+
boundaries << Boundary.new(box2d, Vec2D.new(5, height / 2), Vec2D.new(10, height))
33+
# Make a new blob
34+
@blob = Blob.new
35+
end
36+
37+
def draw
38+
background(255)
39+
# We must always step through time!
40+
boundaries.each(&:display)
41+
# Show the blob!
42+
blob.display
43+
end

examples/blobby/boundary.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
class Boundary
2+
include Processing::Proxy
3+
attr_reader :box2d, :b, :pos, :size, :a
4+
5+
def initialize(b2d, pos, sz, a = 0)
6+
@box2d, @pos, @size, @a = b2d, pos, sz, a
7+
# Define the polygon
8+
sd = PolygonShape.new
9+
# Figure out the box2d coordinates
10+
box2d_w = box2d.scale_to_world(size.x / 2)
11+
box2d_h = box2d.scale_to_world(size.y / 2)
12+
# We're just a box
13+
sd.set_as_box(box2d_w, box2d_h)
14+
# Create the body
15+
bd = BodyDef.new
16+
bd.type = BodyType::STATIC
17+
bd.angle = a
18+
bd.position.set(box2d.processing_to_world(pos.x, pos.y))
19+
@b = box2d.create_body(bd)
20+
# Attached the shape to the body using a Fixture
21+
b.create_fixture(sd, 1)
22+
end
23+
24+
# Draw the boundary, it doesn't move so we don't have to ask the Body for location
25+
def display
26+
fill(0)
27+
stroke(0)
28+
stroke_weight(1)
29+
rect_mode(CENTER)
30+
a = b.get_angle
31+
push_matrix
32+
translate(pos.x, pos.y)
33+
rotate(-a)
34+
rect(0, 0, size.x,size.y)
35+
pop_matrix
36+
end
37+
end

lib/pbox2d.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def import_class_list(list, string)
2727
RevoluteJoint
2828
RevoluteJointDef
2929
MouseJointDef
30+
ConstantVolumeJointDef
3031
)
3132
joint_format = 'org.jbox2d.dynamics.joints.%s'
3233
import_class_list(joint, joint_format)

0 commit comments

Comments
 (0)