pbox2d 0.3.1-java → 0.4.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,136 @@
1
+ require 'forwardable'
2
+
3
+ # The Nature of Code
4
+ # PBox2D example
5
+ # An uneven surface boundary
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))
30
+ end
31
+ # Store the vertex in screen coordinates
32
+ surface << Vec2.new(x, y)
33
+ # Move through perlin noise
34
+ xoff += 0.1
35
+ end
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)
41
+ end
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
65
+
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
@@ -0,0 +1,42 @@
1
+ # The Nature of Code
2
+ # Daniel Shiffman
3
+ # http://natureofcode.com
4
+ # Basic example of falling rectangles
5
+
6
+ require 'pbox2d'
7
+ require_relative 'lib/boundary'
8
+ require_relative 'lib/box'
9
+
10
+ attr_reader :boxes, :boundaries, :box2d
11
+
12
+ def setup
13
+ size(640, 360, P2D)
14
+ @box2d = Box2D.new(self)
15
+ box2d.init_options(gravity: [0, -10])
16
+ box2d.create_world
17
+ @boundaries = []
18
+ @boxes = []
19
+ box2d.world.set_particle_radius(0.15)
20
+ box2d.world.set_particle_damping(0.2)
21
+ boundaries << Boundary.new(self, width / 4, height - 5, width / 2 - 50, 10)
22
+ boundaries << Boundary.new(self, 3 * width / 4, height - 50, width / 2 - 50, 10)
23
+ end
24
+
25
+ def mouse_pressed
26
+ boxes << Box.new(box2d, mouse_x, mouse_y)
27
+ end
28
+
29
+ def draw
30
+ background(255)
31
+ boundaries.each(&:display)
32
+ pos_buffer = box2d.world.particle_position_buffer
33
+ return if pos_buffer.nil?
34
+ stroke(0)
35
+ stroke_weight(2)
36
+ pos_buffer.each do |buf|
37
+ pos = box2d.world_to_processing(buf)
38
+ point(pos.x, pos.y)
39
+ end
40
+ fill(0)
41
+ text(format('f.p.s %d', frame_rate.to_i), 10, 60)
42
+ end
@@ -0,0 +1,36 @@
1
+ require 'pbox2d'
2
+ require_relative 'lib/particle_system'
3
+ attr_reader :box2d, :boundaries, :systems
4
+
5
+ def setup
6
+ size(400, 300)
7
+ @box2d = Box2D.new(self)
8
+ box2d.init_options(gravity: [0, -20])
9
+ box2d.create_world
10
+ # to set a custom gravity otherwise
11
+ # box2d.gravity([0, -20])
12
+ # Create Arrays
13
+ @systems = []
14
+ @boundaries = []
15
+ # Add a bunch of fixed boundaries
16
+ boundaries << Boundary.new(self, 50, 100, 5, -0.3)
17
+ boundaries << Boundary.new(self, 250, 175, 5, 0.5)
18
+ end
19
+
20
+ def draw
21
+ background(255)
22
+ # Run all the particle systems
23
+ if systems.size > 0
24
+ systems.each do |system|
25
+ system.run
26
+ system.add_particles(self, rand(0..2))
27
+ end
28
+ end
29
+ # Display all the boundaries
30
+ boundaries.each(&:display)
31
+ end
32
+
33
+ def mouse_pressed
34
+ # Add a new Particle System whenever the mouse is clicked
35
+ systems << ParticleSystem.new(self, 0, mouse_x, mouse_y)
36
+ end
@@ -0,0 +1,39 @@
1
+ # Basic example of falling rectangles
2
+ require 'pbox2d'
3
+ require_relative 'lib/custom_shape'
4
+
5
+ attr_reader :box2d, :boundaries, :polygons
6
+
7
+ def setup
8
+ size(640, 360)
9
+ smooth
10
+ # Initialize box2d physics and create the world
11
+ @box2d = Box2D.new(self)
12
+ box2d.init_options(gravity: [0, -20])
13
+ 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)
24
+ end
25
+
26
+ def draw
27
+ background(255)
28
+ # Display all the boundaries
29
+ boundaries.each(&:display)
30
+ # 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)
35
+ end
36
+
37
+ def mouse_pressed
38
+ polygons << CustomShape.new(self, mouse_x, mouse_y)
39
+ end
@@ -0,0 +1,141 @@
1
+ require 'pbox2d'
2
+
3
+ # A list we'll use to track fixed objects
4
+ attr_reader :box2d, :boundaries, :boxes
5
+
6
+ java_alias :background_int, :background, [Java::int]
7
+ java_alias :stroke_int, :stroke, [Java::int]
8
+
9
+ def setup
10
+ size(400,300)
11
+ stroke_int(0) # set stroke this way to avoid overload warnings
12
+ srand(5)
13
+ # Initialize box2d physics and create the world
14
+ @box2d = Box2D.new(self)
15
+ puts box2d.version # print out version of pbox2d gem in use
16
+ box2d.init_options(scale: 10, gravity: [0, -20.0])
17
+ box2d.create_world
18
+ # Set a custom gravity
19
+ # box2d.gravity(0, -20)
20
+ # Create ArrayLists
21
+ @boxes = []
22
+ @boundaries = []
23
+ # Add a bunch of fixed boundaries
24
+ boundaries << Boundary.new(self, width / 4, height - 5, width / 2 - 50, 10)
25
+ boundaries << Boundary.new(self, 3 * width / 4, height - 50, width / 2 - 50, 10)
26
+ end
27
+
28
+ def draw
29
+ background_int(255) # set background this way to avoid overload warnings
30
+ # Boxes fall from the top every so often
31
+ boxes << Box.new(self, width / 2, 30) if rand < 0.99
32
+ boundaries.each(&:display)
33
+ boxes.each(&:display)
34
+ # Boxes that leave the screen, we delete them note they have to be deleted
35
+ # from both the box2d world and locally
36
+ boxes.reject!(&:done)
37
+ exit if frame_count >= 908
38
+ end
39
+
40
+ class Boundary
41
+ extend Forwardable
42
+ def_delegators(:@app, :box2d, :fill, :rect, :rect_mode)
43
+ # A boundary is a simple rectangle with x, y, width, and height
44
+ attr_reader :x, :y, :w, :h, :b
45
+
46
+ def initialize(app, x ,y, w, h)
47
+ @app, @x ,@y, @w, @h = app, x ,y, w, h
48
+ # Create the body
49
+ bd = BodyDef.new
50
+ bd.position.set(box2d.processing_to_world(x, y))
51
+ @b = box2d.create_body(bd)
52
+ # Figure out the box2d coordinates
53
+ box2d_w = box2d.scale_to_world(w / 2)
54
+ box2d_h = box2d.scale_to_world(h / 2)
55
+ # Define the polygon
56
+ sd = PolygonShape.new
57
+ sd.setAsBox(box2d_w, box2d_h)
58
+ fd = FixtureDef.new
59
+ fd.shape = sd
60
+ fd.density = 0
61
+ fd.friction = 0.3
62
+ fd.restitution = 0.5
63
+ b.createFixture(fd)
64
+ end
65
+
66
+ # Draw the boundary, if it were at an angle we'd have to do something fancier
67
+ def display
68
+ fill(0)
69
+ rect_mode(Java::ProcessingCore::PConstants::CENTER)
70
+ rect(x, y, w, h)
71
+ end
72
+ end
73
+
74
+ # A rectangular box
75
+ class Box
76
+ extend Forwardable
77
+ def_delegators(:@app, :box2d, :rect_mode, :rect,
78
+ :push_matrix, :pop_matrix, :fill, :rotate,
79
+ :stroke, :stroke_weight, :translate)
80
+ # We need to keep track of a Body and a width and height
81
+ attr_reader :body, :w, :h
82
+
83
+ # Constructor
84
+ def initialize(app, x, y)
85
+ @w = rand(4..16)
86
+ @h = rand(4..16)
87
+ @app = app
88
+ # Add the box to the box2d world
89
+ make_body(Vec2.new(x, y), w, h)
90
+ end
91
+
92
+ def done
93
+ # Let's find the screen position of the particle
94
+ pos = box2d.body_coord(body)
95
+ # Is it off the bottom of the screen?
96
+ return false unless (pos.y > box2d.height + w * h)
97
+ box2d.destroy_body(body)
98
+ true
99
+ end
100
+
101
+ # Drawing the box
102
+ def display
103
+ # We look at each body and get its screen position
104
+ pos = box2d.body_coord(body)
105
+ # Get its angle of rotation
106
+ a = body.angle
107
+ rect_mode(Java::ProcessingCore::PConstants::CENTER)
108
+ push_matrix
109
+ translate(pos.x, pos.y)
110
+ rotate(-a)
111
+ fill(175)
112
+ rect(0, 0, w, h)
113
+ pop_matrix
114
+ end
115
+
116
+ # This function adds the rectangle to the box2d world
117
+ def make_body(center, w, h)
118
+ # Define a polygon (this is what we use for a rectangle)
119
+ sd = PolygonShape.new
120
+ box2d_w = box2d.scale_to_world(w / 2)
121
+ box2d_h = box2d.scale_to_world(h / 2)
122
+ sd.setAsBox(box2d_w, box2d_h)
123
+ # Define a fixture
124
+ fd = FixtureDef.new
125
+ fd.shape = sd
126
+ # Parameters that affect physics
127
+ fd.density = 1
128
+ fd.friction = 0.3
129
+ fd.restitution = 0.5
130
+ # Define the body and make it from the shape
131
+ bd = BodyDef.new
132
+ bd.type = BodyType::DYNAMIC
133
+ bd.position.set(box2d.processing_to_world(center))
134
+ cs = CircleShape.new
135
+ @body = box2d.create_body(bd)
136
+ body.create_fixture(fd)
137
+ # Give it some initial random velocity
138
+ body.setLinearVelocity(Vec2.new(rand(-5.0..5), rand(2.0..5)))
139
+ body.setAngularVelocity(rand(-5.0..5))
140
+ end
141
+ end
@@ -0,0 +1,68 @@
1
+ # The Nature of Code
2
+ # Daniel Shiffman
3
+ # http://natureofcode.com
4
+ require 'forwardable'
5
+
6
+ # A rectangular box
7
+ class Box
8
+ extend Forwardable
9
+ def_delegators(:@app, :push_matrix, :pop_matrix, :fill, :rotate, :box2d,
10
+ :stroke_weight, :translate, :rect_mode, :stroke, :rect)
11
+ # We need to keep track of a Body and a width and height
12
+ attr_reader :body, :w, :h
13
+
14
+ # Constructor
15
+ def initialize(x, y, w, h, lock)
16
+ @w, @h = w, h
17
+ @app = $app
18
+ # Define and create the body
19
+ bd = BodyDef.new
20
+ bd.position.set(box2d.processing_to_world(Vec2.new(x, y)))
21
+ bd.type = lock ? BodyType::STATIC : BodyType::DYNAMIC
22
+
23
+ @body = box2d.createBody(bd)
24
+
25
+ # Define the shape -- a (this is what we use for a rectangle)
26
+ sd = PolygonShape.new
27
+ box2dW = box2d.scale_to_world(w / 2)
28
+ box2dH = box2d.scale_to_world(h / 2)
29
+ sd.setAsBox(box2dW, box2dH)
30
+
31
+ # Define a fixture
32
+ fd = FixtureDef.new
33
+ fd.shape = sd
34
+ # Parameters that affect physics
35
+ fd.density = 1
36
+ fd.friction = 0.3
37
+ fd.restitution = 0.5
38
+
39
+ body.createFixture(fd)
40
+
41
+ # Give it some initial random velocity
42
+ body.setLinearVelocity(Vec2.new(rand(-5..5),rand(2..5)))
43
+ body.setAngularVelocity(rand(-5..5))
44
+ end
45
+
46
+ # This function removes the particle from the box2d world
47
+ def killBody
48
+ box2d.destroyBody(body)
49
+ end
50
+
51
+ # Drawing the box
52
+ def display
53
+ # We look at each body and get its screen position
54
+ pos = box2d.body_coord(body)
55
+ # Get its angle of rotation
56
+ a = body.getAngle
57
+
58
+ rect_mode(Java::ProcessingCore::PConstants::CENTER)
59
+ push_matrix
60
+ translate(pos.x,pos.y)
61
+ rotate(-a)
62
+ fill(127)
63
+ stroke(0)
64
+ stroke_weight(2)
65
+ rect(0,0,w,h)
66
+ pop_matrix
67
+ end
68
+ end