motion/joybox/physics/world.rb in joybox-1.0.0 vs motion/joybox/physics/world.rb in joybox-1.1.0
- old
+ new
@@ -1,77 +1,148 @@
module Joybox
module Physics
class World < B2DWorld
- def self.defaults
+ extend Joybox::Common::Initialize
+
+ alias_method :bodies, :bodyList
+ alias_method :allows_sleeping?, :allowsSleeping
+ alias_method :allows_sleeping=, :setAllowsSleeping
+ alias_method :proxy_count, :proxyCount
+ alias_method :body_count, :bodyCount
+ alias_method :joint_count, :jointCount
+ alias_method :contact_count, :contactCount
+ alias_method :tree_height, :treeHeight
+ alias_method :tree_balance, :treeBalance
+ alias_method :tree_quality, :treeQuality
+ alias_method :locked?, :isLocked
+ alias_method :auto_clear_forces?, :autoClearForces
+ alias_method :auto_clear_forces=, :setAutoClearForces
+ alias_method :create_body, :createBody
+ alias_method :clear_forces, :clearForces
+ alias_method :draw_debug_data, :drawDebugData
+ alias_method :continuous_physics, :continuousPhysics
+
+ def defaults
{
gravity: [0, 0],
- allows_sleeping: true,
- continuous_physics: true
+ allows_sleeping: true
}
end
-
- def self.new(options)
-
+ def initialize(options = {})
options = options.nil? ? defaults : defaults.merge!(options)
- world = World.alloc.init
-
- world.gravity = options[:gravity]
- world.allowsSleeping = options[:allows_sleeping]
- world.continuousPhysics = options[:continuous_physics]
-
- world
+ init
+ self.gravity = options[:gravity]
+ self.allowsSleeping = options[:allows_sleeping]
end
-
def step_defaults
{
velocity_interactions: 8,
position_interactions: 1
}
end
-
def step(options = {})
-
options = options.nil? ? step_defaults : step_defaults.merge!(options)
stepWithDelta(options[:delta],
- velocityInteractions: options[:velocity_interactions],
- positionInteractions: options[:position_interactions])
+ velocityInteractions: options[:velocity_interactions],
+ positionInteractions: options[:position_interactions])
end
-
def new_body(options = {}, &block)
body = Body.new(self, options)
body.instance_eval(&block) if block
body
end
+ def destroy_body(body)
+ destroyBody(body)
+ @listening_sprites.delete(body[:sprite]) unless @listening_sprites.nil?
+ end
- def setup_collision_listener
+ def should_collide(&block)
+ @should_collide = block
+ @contact_filter = B2DContactFilter.new;
+ @contact_filter.shouldCollide = lambda do |first_fixture, second_fixture|
+ @should_collide.call(first_fixture, second_fixture)
+ end
+
+ setContactFilter(@contact_filter)
+ end
+
+ def setup_collision_listener
@contact_listener = B2DContactListener.new
- addContactListener(@contact_listener)
+ setContactListener(@contact_listener)
- @listening_bodies = Hash.new
+ @listening_sprites = Hash.new
- @contact_listener.beginContact = lambda { | first_body, second_body, is_touching |
+ @contact_listener.beginContact = lambda do |first_body, second_body, is_touching|
+ # TODO: Find a better way to do this assignment
+ collision = [first_body, second_body] if @listening_sprites.has_key? first_body[:sprite]
+ collision = [second_body, first_body] if @listening_sprites.has_key? second_body[:sprite]
+
+ unless collision.nil?
+ object = collision[1][:sprite].nil? ? collision[1] : collision[1][:sprite]
+ @listening_sprites[collision[0][:sprite]].call(object, is_touching)
+ end
- @listening_bodies[first_body].call(second_body, is_touching) if @listening_bodies.include? first_body
- @listening_bodies[second_body].call(first_body, is_touching) if @listening_bodies.include? second_body
- }
+ @on_collision.call(first_body, second_body, is_touching) unless @on_collision.nil?
+ end
end
+ def when_collide(sprite, &block)
+ setup_collision_listener unless @contact_listener
+ @listening_sprites[sprite] = block
+ end
- def when_collide(body, &block)
-
+ def on_collision(&block)
setup_collision_listener unless @contact_listener
+ @on_collision = block
+ end
- @listening_bodies[body] = block
+ def on_fixture_destroyed(&block)
+ @when_fixture_destroyed = block
+
+ @destruction_listener = B2DDestructionListener.new;
+ @destruction_listener.fixtureSayGoodbye = lambda do |fixture|
+ @when_fixture_destroyed.call(fixture)
+ end
+
+ setDestructionListener(@destruction_listener)
+ end
+
+ def query(options = {}, &block)
+ @query = block
+ @query_callback = B2DQueryCallback.new
+ @query_callback.reportFixture = lambda do |fixture|
+ @query.call(fixture)
+ end
+
+ aabb = AABB.new
+ aabb.lower_bound = CGPointMake(options[:lower_bound][0], options[:lower_bound][1])
+ aabb.upper_bound = CGPointMake(options[:upper_bound][0], options[:upper_bound][1])
+ queryAABBWithCallback(@query_callback, andAABB:aabb)
+ end
+
+ def ray_cast(options = {}, &block)
+ @ray_cast = block
+ @ray_cast_callback = B2DRayCastCallback.new
+ @ray_cast_callback.reportFixture = lambda do |fixture, point, normal, fraction|
+ @ray_cast.call(fixture, point.from_pixel_coordinates, normal, fraction)
+ end
+
+ first_point = CGPointMake(options[:first_point][0], options[:first_point][1])
+ second_point = CGPointMake(options[:second_point][0], options[:second_point][1])
+
+ rayCastWithCallback(@ray_cast_callback,
+ andPoint1:first_point.from_pixel_coordinates,
+ andPoint2:second_point.from_pixel_coordinates)
end
end
end