pbox2d 0.4.2-java → 0.5.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -0
  3. data/CHANGELOG.md +37 -0
  4. data/CONTRIBUTING.md +30 -0
  5. data/Gemfile +4 -0
  6. data/LICENCE +25 -0
  7. data/LICENSE.md +1 -3
  8. data/README.md +3 -3
  9. data/Rakefile +19 -81
  10. data/examples/README.md +7 -0
  11. data/examples/bumpy_surface_noise.rb +11 -7
  12. data/examples/collision_listening.rb +30 -0
  13. data/examples/data/java_args.txt +2 -0
  14. data/examples/distance_joint/distance_joint.rb +8 -5
  15. data/examples/lib/boundary.rb +22 -13
  16. data/examples/lib/box.rb +1 -2
  17. data/examples/lib/custom_listener.rb +29 -0
  18. data/examples/lib/custom_shape.rb +5 -3
  19. data/examples/lib/particle.rb +77 -0
  20. data/examples/lib/particle_system.rb +25 -65
  21. data/examples/lib/shape_system.rb +5 -3
  22. data/examples/lib/surface.rb +1 -1
  23. data/examples/liquid_fun_test.rb +11 -5
  24. data/examples/liquidy.rb +18 -14
  25. data/examples/mouse_joint/boundary.rb +1 -1
  26. data/examples/mouse_joint/box.rb +1 -1
  27. data/examples/mouse_joint/dummy_spring.rb +2 -3
  28. data/examples/mouse_joint/mouse_joint.rb +7 -8
  29. data/examples/polygons.rb +16 -16
  30. data/examples/quick_test.rb +33 -63
  31. data/examples/revolute_joint/revolute_joint.rb +5 -1
  32. data/examples/test_contact/README.md +6 -0
  33. data/examples/test_contact/lib/boundary.rb +1 -1
  34. data/examples/test_contact/lib/particle.rb +3 -3
  35. data/examples/test_contact/test_contact.rb +2 -1
  36. data/lib/box2d.jar +0 -0
  37. data/lib/jbox2d-library-2.3.1-SNAPSHOT.jar +0 -0
  38. data/lib/pbox2d/box2d.rb +1 -1
  39. data/lib/pbox2d/version.rb +2 -3
  40. data/pbox2d.gemspec +33 -0
  41. data/pom.xml +146 -0
  42. data/src/processing/box2d/Box2DProcessing.java +319 -0
  43. data/src/processing/box2d/Options.java +52 -0
  44. data/src/processing/box2d/Step.java +44 -0
  45. metadata +46 -34
  46. data/lib/jbox2d-library-2.2.1-ds.jar +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1ff8899781cd0308635cb95b3f78b9e3789d345d
4
- data.tar.gz: 37b9df883bb1730e4f7129aebe65acd7c8b6a86e
3
+ metadata.gz: 892dc4c6bb63dfa90f257605378cf40da48bed18
4
+ data.tar.gz: 58a5e3b1de46dad55499d945ca32f8bfc5dbe623
5
5
  SHA512:
6
- metadata.gz: 9c6218dacd978b3c530fea1d4df318d6281c4e265a4140c9bc0a376487dbd9f76e1e8aedd28d06736b40d59c00da33421030e1ebe765431c102eeaeccccc26f1
7
- data.tar.gz: 6ed60e48763528a00bdad9f0d6a93e49dfa8b5802d3acac0293bf49c13dd84161930f5bc37fad65efa4786acc5c536db3ce8ee5930131c89eaa6657fc822cb2d
6
+ metadata.gz: cc18b5cb955557edc6e2989591201cd8d397afe6317bf787816eafcf444b31d9f3a53412e9e65a872b0c52af1d906abd181545d43d5cf1b4348f11939d74b70d
7
+ data.tar.gz: 75b35aabdbe6c41bed94efeab684b5c533e8461106c488464c4a6bb74899eb83a860d0886ed77b78a6fe95c8a6f4a23985e5d5e31b04b9526d9898c839aca4f3
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ *~
2
+ *.jar
3
+ *.gem
4
+ *.swp
5
+ /.bundle/
6
+ /.yardoc
7
+ /Gemfile.lock
8
+ /_yardoc/
9
+ /coverage/
10
+ /doc/
11
+ /pkg/
12
+ /spec/reports/
13
+ /tmp/
14
+ /target/
15
+ MANIFEST.MF
data/CHANGELOG.md ADDED
@@ -0,0 +1,37 @@
1
+ ### v0.5.0.pre
2
+
3
+ Break compatability with ruby-processing. New build uses maven. Works with JRuby-9.0.3.0, processing-3.0.1 and jdk8.
4
+
5
+
6
+ ### v0.4.2
7
+
8
+ Re-factor extension class, last release for ruby-processing (processing-2.2.1) getting read for JRubyArt version.
9
+
10
+ ### v0.4.1
11
+
12
+ Favour explicit import of classes to package include. Use forwardable in examples to make usable in both JRubyArt and ruby-processing, further to demonstrate alternative to including Processing::Proxy to get 'inner class' like access to processing methods, in own classes.
13
+
14
+ ### v0.3.1
15
+
16
+ Need to be less specific about ruby-processing version
17
+
18
+ ### v0.3.0 (was v0.2.1 but bumped version because it features new functionality)
19
+
20
+ Finally got ContactListener to work (currently best plan is to create your own CustomListener, see example test_contact)
21
+
22
+ ### v0.2.0
23
+
24
+ Moving away from Shiffman Box2D design, to create a more ruby like interface added Step and Option classes to make it easier to initialize runtime and step options. On the ruby side options may/should be set with hash input. Gravity may still be set dynamically, but unless it is going to change it should be set via `init_options`. Unless `init_options` or `step_options` are set, defaults on java side are used.
25
+
26
+ ### v0.1.1
27
+
28
+ Make common classes avaiable directly, expose sketch eight.
29
+
30
+ ### v0.1.0
31
+
32
+ Now require 'pbox2d' matches gem name, refactor java methods by removing unnecessary get/set/pixel. Also prefer to world and to processing. Adjust examples, bump version to denote significant change.
33
+
34
+
35
+ ### v0.0.1
36
+
37
+ First release, works but require name 'box2d' doesn't match gem name it is confusing
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,30 @@
1
+ ## Contributing
2
+ In the spirit of [free software][free-sw], **everyone** is encouraged to help improve this project.
3
+
4
+ Here are some ways *you* can contribute:
5
+
6
+ * by reporting bugs
7
+ * by suggesting/implementing new features
8
+ * by writing or editing documentation
9
+ * by contributing examples ( _show your creativity, or translate someone elses masterpiece_ )
10
+ * by closing [issues][]
11
+ * by supporting [Processing.org][], nothing to do with us but we rely on them
12
+
13
+ ## Submitting an Issue
14
+ We use the [GitHub issue tracker][issues] to track bugs and features. Before
15
+ submitting a bug report or feature request, check to make sure it hasn't
16
+ already been submitted. When submitting a bug report, ideally include a [Gist][]
17
+ that includes a stack trace and any details that may be necessary to reproduce
18
+ the bug, including your gem version, Ruby version, and operating system.
19
+
20
+
21
+ ## Submitting a Pull Request
22
+ 1. [Fork the repository.][fork]
23
+ 2. [Submit a pull request.][pr]
24
+
25
+ [free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
26
+ [issues]: https://github.com/ruby-processing/jbox2d/issues
27
+ [gist]: https://gist.github.com/
28
+ [fork]: http://help.github.com/fork-a-repo/
29
+ [pr]: http://help.github.com/send-pull-requests/
30
+ [processing.org]: http://processing.org/foundation/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pbox2d.gemspec
4
+ gemspec
data/LICENCE ADDED
@@ -0,0 +1,25 @@
1
+ JBox2d binary licence
2
+
3
+ Copyright (c) 2014, Daniel Murphy
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without modification,
7
+ are permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright notice, this
13
+ list of conditions and the following disclaimer in the documentation and/or
14
+ other materials provided with the distribution.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
20
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/LICENSE.md CHANGED
@@ -31,6 +31,4 @@ recognized licences.....
31
31
  For my part I lean toward GPL3 but MIT is OK and matches ruby-processing and
32
32
  vanilla processing.
33
33
 
34
- Copyright (c) 2014, Martin Prout
35
-
36
-
34
+ Copyright (c) 2014-2015, Martin Prout
data/README.md CHANGED
@@ -30,7 +30,7 @@ Copyright (c) 2014 Daniel Shiffman
30
30
 
31
31
  This gem was created by Martin Prout
32
32
 
33
- Copyright (c) 2014-2015 Martin Prout
33
+ Copyright (c) 2015 Martin Prout
34
34
 
35
35
  ### To compile
36
36
 
@@ -60,6 +60,6 @@ The other thing you should know is there is a mismatch between the physics world
60
60
  [Nature of Code book]:http://natureofcode.com/
61
61
  [Sandi Metz]:http://www.poodr.com/
62
62
  [this book]:http://www.crcpress.com/product/isbn/9781466565760
63
- [zip]:https://github.com/ruby-processing/jbox2d/archive/0.4.2.zip
64
- [tar]:https://github.com/ruby-processing/jbox2d/archive/0.4.2.tar.gz
63
+ [zip]:https://github.com/ruby-processing/jbox2d/archive/0.5.0-pre.zip
64
+ [tar]:https://github.com/ruby-processing/jbox2d/archive/0.5.0-pre.tar.gz
65
65
  [Wiki]:https://github.com/ruby-processing/jbox2d/wiki
data/Rakefile CHANGED
@@ -2,100 +2,38 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'rake/clean'
4
4
  require 'rubygems/package_task'
5
- require 'rdoc/task'
6
5
  require 'rake/testtask'
7
- require 'rspec/core/rake_task'
8
- require_relative 'lib/pbox2d/version'
9
-
10
- spec = Gem::Specification.new do |s|
11
- s.name = 'pbox2d'
12
- s.version = Pbox2D::VERSION
13
- s.has_rdoc = true
14
- s.extra_rdoc_files = ['README.md', 'LICENSE.md']
15
- s.summary = 'jbox2d wrapped in a gem for ruby-processing'
16
- s.description = <<-EOF
17
- "An exemplar for how processing/java libraries can be made available
18
- for use in ruby-processing. In this example avoiding an overdose of java
19
- reflection by letting jruby sugar implement an interface"
20
- EOF
21
- s.license = 'MIT'
22
- s.authors = ['Martin Prout']
23
- s.email = 'martin_p@lineone.net'
24
- s.homepage = 'https://github.com/ruby-processing/jbox2d'
25
- s.files = %w(LICENSE.md README.md Rakefile) + FileList['lib/**/*.rb', 'examples/**/*.rb']
26
- s.files << 'lib/box2d.jar'
27
- s.files << 'lib/jbox2d-library-2.2.1-ds.jar'
28
- s.require_path = 'lib'
29
- s.add_dependency 'ruby-processing', '~> 2.6', '>= 2.6.4'
30
- s.add_development_dependency "rake", "~> 10.3"
31
- s.add_development_dependency "rake-compiler", "~> 0.9"
32
- s.platform='java'
33
- s.requirements << 'A decent graphics card'
34
- s.requirements << 'java runtime >= 1.7+'
35
- s.requirements << 'processing = 2.2.1+'
36
- end
37
-
38
- # -*- ruby -*-
39
-
40
- require 'java'
41
- require 'rake/javaextensiontask'
42
6
 
43
- # -*- encoding: utf-8 -*-
44
- require 'psych'
7
+ require_relative 'lib/pbox2d/version'
45
8
 
46
- def copy_jars(name, dest)
47
- conf = '~/.jruby_art/config.yml'
48
- begin
49
- path = File.expand_path(conf)
50
- rp_config = (Psych.load_file(path))
51
- source= "#{rp_config["PROCESSING_ROOT"]}/core/library/"
52
- rescue
53
- raise "WARNING: you must set PROCESSING_ROOT in #{conf} compile"
9
+ def create_manifest
10
+ title = 'Implementation-Title: box2d (pbox2d java extension for JRubyArt)'
11
+ version = format('Implementation-Version: %s', Pbox2d::VERSION)
12
+ file = File.open('MANIFEST.MF', 'w') do |f|
13
+ f.puts(title)
14
+ f.puts(version)
54
15
  end
55
- body = proc {
56
- Dir["#{source}/core.jar"].each do |f|
57
- puts "Copying #{f} To #{dest}"
58
- FileUtils.cp f, dest
59
- end
60
- }
61
- Rake::Task.define_task(name, &body)
62
16
  end
63
17
 
64
- copy_jars(:processing_jars, 'lib')
18
+ task default: [:init, :compile, :gem]
65
19
 
66
- Rake::JavaExtensionTask.new('processing') do |ext|
67
- jars = FileList['lib/*.jar']
68
- ext.classpath = jars.map { |x| File.expand_path x}.join ':'
69
- ext.name = 'box2d'
70
- ext.debug = true
71
- ext.lib_dir = 'lib'
72
- ext.source_version='1.7'
73
- ext.target_version='1.7'
20
+ desc 'Create Manifest'
21
+ task :init do
22
+ create_manifest
74
23
  end
75
24
 
76
- Gem::PackageTask.new(spec) do |p|
77
- p.gem_spec = spec
78
- p.need_tar = true
79
- p.need_zip = true
25
+ desc 'Compile'
26
+ task :compile do
27
+ sh "mvn package"
28
+ sh "mvn dependency:copy"
29
+ sh "mv target/box2d.jar lib"
80
30
  end
81
31
 
82
- Rake::RDocTask.new do |rdoc|
83
- files = ['README.md', 'LICENSE.md'] + FileList['lib/**/*.rb']
84
-
85
- rdoc.rdoc_files.add(files)
86
- rdoc.main = "README.md" # page to start on
87
- rdoc.title = "Box2D Docs"
88
- rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
89
- rdoc.options << '--line-numbers'
32
+ desc 'Build Gem'
33
+ task :gem do
34
+ sh "gem build pbox2d.gemspec"
90
35
  end
91
36
 
92
37
  Rake::TestTask.new do |t|
93
38
  t.test_files = FileList['test/**/*.rb']
94
39
  end
95
-
96
- RSpec::Core::RakeTask.new do |spec|
97
- spec.pattern = 'spec/*_spec.rb'
98
- spec.rspec_opts = [Dir["lib"].to_a.join(':')]
99
- end
100
-
101
-
@@ -0,0 +1,7 @@
1
+ ### Source of Sketches
2
+
3
+ These sketches have been translated from 'vanilla processing sketches' by Dan Shiffman. The original sketches were designed to run with the Box2D-for-processing library which has a subtlely different interface from the pbox2d gem. There is probably scope for further refactoring of most of the sketches to make them more ruby-like (the mouse_joint example has perhaps travelled furthest from the original version).
4
+
5
+ ### java_args.txt
6
+
7
+ The `data` folder contains java_args.txt, which currently silently enables the OpenGl-based pipeline using `-Dsun.java2d.opengl=true` add any other java args here, use `True` instead of `true` to get a message.
@@ -5,11 +5,10 @@
5
5
  require 'pbox2d'
6
6
  require_relative 'lib/surface'
7
7
 
8
- attr_reader :surface, :box2d, :particles
8
+ attr_reader :srface, :box2d, :particles
9
9
 
10
10
  def setup
11
- size(500, 300)
12
- smooth 4
11
+ sketch_title 'Bumpy Surface Noise'
13
12
  # Initialize box2d physics and create the world
14
13
  @box2d = Box2D.new(self)
15
14
  box2d.init_options(gravity: [0, -20])
@@ -18,16 +17,16 @@ def setup
18
17
  # box2d.gravity([0, -20])
19
18
  # Create the empty list
20
19
  @particles = []
21
- # Create the surface
22
- @surface = Surface.new(self)
20
+ # Create the srface
21
+ @srface = Surface.new(self)
23
22
  end
24
23
 
25
24
  def draw
26
25
  # If the mouse is pressed, we make new particles
27
26
  # We must always step through time!
28
27
  background(138, 66, 54)
29
- # Draw the surface
30
- surface.display
28
+ # Draw the srface
29
+ srface.display
31
30
  # NB ? reqd to call mouse_pressed value, else method gets called.
32
31
  particles << Particle.new(self, mouse_x, mouse_y, rand(2.0..6)) if mouse_pressed?
33
32
  # Draw all particles
@@ -39,3 +38,8 @@ def draw
39
38
  fill(0)
40
39
  text(format('framerate: %d', frame_rate), 12, 16)
41
40
  end
41
+
42
+ def settings
43
+ size(500, 300)
44
+ smooth 4
45
+ end
@@ -0,0 +1,30 @@
1
+ require 'pbox2d'
2
+ require 'forwardable'
3
+ require_relative 'lib/custom_listener'
4
+ require_relative 'lib/particle'
5
+ require_relative 'lib/boundary'
6
+
7
+ attr_reader :box2d, :particles, :wall
8
+
9
+ Vect = Struct.new(:x, :y)
10
+
11
+ def settings
12
+ size 400, 400
13
+ end
14
+
15
+ def setup
16
+ sketch_title 'Collision Listening'
17
+ @box2d = Box2D.new(self)
18
+ box2d.create_world
19
+ box2d.add_listener(CustomListener.new)
20
+ @particles = []
21
+ @wall = Boundary.new(box2d, Vect.new(width / 2, height - 5), Vect.new(width, 10))
22
+ end
23
+
24
+ def draw
25
+ background(255)
26
+ particles << Particle.new(self, rand(width), 20, rand(4..8)) if rand < 0.1
27
+ particles.each(&:display)
28
+ particles.reject!(&:done)
29
+ wall.display
30
+ end
@@ -0,0 +1,2 @@
1
+ -XX:CompileCommand=dontinline,org.jruby.runtime.invokedynamic.InvokeDynamicSupport::invocationFallback
2
+
@@ -14,16 +14,19 @@ require_relative 'particle_system'
14
14
 
15
15
  attr_reader :box2d, :boundaries, :system
16
16
 
17
- def setup
17
+ def settings
18
18
  size(640, 360)
19
+ end
20
+
21
+ def setup
19
22
  # Initialize box2d physics and create the world
20
23
  @box2d = Box2D.new(self)
21
24
  box2d.create_world
22
25
  @system = ParticleSystem.new
23
- @boundaries = [
24
- Boundary.new(width / 4, height - 5, width / 2 - 50, 10),
25
- Boundary.new(3 * width / 4, height - 50, width / 2 - 50, 10)
26
- ]
26
+ @boundaries = []
27
+ # Add a bunch of fixed boundaries
28
+ boundaries << Boundary.new(width / 4, height - 5, width / 2 - 50, 10)
29
+ boundaries << Boundary.new(3 * width / 4, height - 50, width / 2 - 50, 10)
27
30
  end
28
31
 
29
32
  def draw
@@ -1,28 +1,37 @@
1
- # The boundary class is used to create fixtures
2
1
  class Boundary
3
- extend Forwardable
4
- def_delegators(:@app, :fill, :stroke, :rect, :rect_mode, :box2d)
5
- attr_reader :pos, :size, :b, :x, :y, :w, :h
6
- def initialize(app, x, y, w, h)
7
- @app, @x, @y, @w, @h = app, x, y, w, h
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
8
  sd = PolygonShape.new
9
- box2d_w = box2d.scale_to_world(w / 2)
10
- box2d_h = box2d.scale_to_world(h / 2)
11
- sd.setAsBox(box2d_w, box2d_h)
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)
12
14
  # Create the body
13
15
  bd = BodyDef.new
14
16
  bd.type = BodyType::STATIC
15
- bd.position.set(box2d.processing_to_world(x, y))
17
+ bd.angle = a
18
+ bd.position.set(box2d.processing_to_world(pos.x, pos.y))
16
19
  @b = box2d.create_body(bd)
17
20
  # Attached the shape to the body using a Fixture
18
21
  b.create_fixture(sd, 1)
19
22
  end
20
23
 
21
- # Draw the boundary, if it were at an angle we'd have to do something fancier
24
+ # Draw the boundary, it doesn't move so we don't have to ask the Body for location
22
25
  def display
23
26
  fill(0)
24
27
  stroke(0)
25
- rect_mode(Java::ProcessingCore::PConstants::CENTER)
26
- rect(x, y, w, h)
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
27
36
  end
28
37
  end
data/examples/lib/box.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # A Box class, note how to access class ParticleGroupDef in jruby
2
- # which is imported into the PB module and not into global namespace
3
- # mainly because of probable name conflict with ParticleSystem
2
+ # which is imported into PB module (not in global namespace)
4
3
  class Box
5
4
  attr_accessor :pg
6
5
  def initialize(b2d, x, y)
@@ -0,0 +1,29 @@
1
+ # A custom listener allows us to get the physics engine to
2
+ # to call our code, on say contact (collisions)
3
+ class CustomListener
4
+ include ContactListener
5
+
6
+ def begin_contact(cp)
7
+ # Get both fixtures
8
+ f1 = cp.getFixtureA
9
+ f2 = cp.getFixtureB
10
+ # Get both bodies
11
+ b1 = f1.getBody
12
+ b2 = f2.getBody
13
+ # Get our objects that reference these bodies
14
+ o1 = b1.getUserData
15
+ o2 = b2.getUserData
16
+ return unless [o1, o2].all? { |obj| obj.respond_to?(:change) }
17
+ o1.change
18
+ o2.change
19
+ end
20
+
21
+ def end_contact(_cp)
22
+ end
23
+
24
+ def pre_solve(_cp, _m)
25
+ end
26
+
27
+ def post_solve(_cp, _ci)
28
+ end
29
+ end
@@ -4,9 +4,9 @@ class CustomShape
4
4
  attr_reader :body, :box2d
5
5
 
6
6
  # Constructor
7
- def initialize(app, x, y)
7
+ def initialize(b2d, x, y)
8
8
  # Add the box to the box2d world
9
- @box2d = app.box2d
9
+ @box2d = b2d
10
10
  make_body(Vec2.new(x, y))
11
11
  end
12
12
 
@@ -69,4 +69,6 @@ class CustomShape
69
69
  body.set_linear_velocity(Vec2.new(rand(-5.0..5), rand(2.0..5)))
70
70
  body.set_angular_velocity(rand(-5.0..5))
71
71
  end
72
- end
72
+ end
73
+
74
+
@@ -0,0 +1,77 @@
1
+ # Note the particle class change method is use to change color to red
2
+ # when two particles collide (no change just hitting boundary)
3
+ class Particle
4
+ extend Forwardable
5
+ def_delegators(:@app, :box2d, :begin_shape, :color, :end_shape, :line, :pop_matrix,
6
+ :ellipse, :translate, :rotate, :stroke, :push_matrix, :fill,
7
+ :no_fill, :stroke_weight)
8
+ attr_accessor :body
9
+ attr_reader :radius, :col
10
+
11
+ def initialize(app, x, y, r)
12
+ @app, @x, @y, @radius = app, x, y, r
13
+ # This function puts the particle in the Box2d world
14
+ make_body(x, y, radius)
15
+ @col = color('#c0c0c0') # silvergrey
16
+ body.setUserData(self)
17
+ end
18
+
19
+ # This function removes the particle from the box2d world
20
+ def kill_body
21
+ box2d.destroy_body(body)
22
+ end
23
+
24
+ # Change color when hit
25
+ def change
26
+ @col = color('#cc0000') # red
27
+ end
28
+
29
+ # Is the particle ready for deletion?
30
+ def done
31
+ # Let's find the screen position of the particle
32
+ pos = box2d.body_coord(body)
33
+ # Is it off the bottom of the screen?
34
+ return false unless pos.y > (box2d.height + radius * 2)
35
+ kill_body
36
+ true
37
+ end
38
+
39
+ def display
40
+ # We look at each body and get its screen position
41
+ pos = box2d.body_coord(body)
42
+ # Get its angle of rotation
43
+ a = body.get_angle
44
+ push_matrix
45
+ translate(pos.x, pos.y)
46
+ rotate(a)
47
+ fill(col)
48
+ stroke(0)
49
+ stroke_weight(1)
50
+ ellipse(0, 0, radius * 2, radius * 2)
51
+ # Let's add a line so we can see the rotation
52
+ line(0, 0, radius, 0)
53
+ pop_matrix
54
+ end
55
+
56
+ # Here's our function that adds the particle to the Box2D world
57
+ def make_body(x, y, r)
58
+ # Define a body
59
+ bd = BodyDef.new
60
+ # Set its position
61
+ bd.position = box2d.processing_to_world(x, y)
62
+ bd.type = BodyType::DYNAMIC
63
+ @body = box2d.create_body(bd)
64
+ # Make the body's shape a circle
65
+ cs = CircleShape.new
66
+ cs.m_radius = box2d.scale_to_world(r)
67
+ fd = FixtureDef.new
68
+ fd.shape = cs
69
+ # Parameters that affect physics
70
+ fd.density = 1
71
+ fd.friction = 0.01
72
+ fd.restitution = 0.3
73
+ # Attach fixture to body
74
+ body.create_fixture(fd)
75
+ body.set_angular_velocity(rand(-10.0..10))
76
+ end
77
+ end