|
| 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 |
0 commit comments