Class: Metro::UI::Space

Inherits:
Model
  • Object
show all
Defined in:
lib/metro/models/ui/space.rb

Overview

Adds a 2D Physics Space to the Scene

Adding a space to a scene allows for objects with a ‘body` and `shape` to be added and affected by collisions and gravity.

Examples:

Adding a space to the scene


class MainScene < GameScene
  draw :space, model: "metro::ui::space"
  draw :hero, position: Game.center

  def show
    space.add_object(hero)
    space.gravity_affects(hero)
  end

  def update
    space.step
    space.clean_up
  end
end

See Also:

Constant Summary

Constants included from Metro::Units

Metro::Units::Bounds

Instance Attribute Summary collapse

Attributes inherited from Model

#scene, #window

Instance Method Summary collapse

Methods inherited from Model

#_load, #_save, #after_initialize, #bounds, #create, #draw, #draw_completed?, hierarchy, inherited, #initialize, metro_name, #model, model_name, models, #name, #notification, #saveable_to_view, #to_hash, #update_completed?

Methods included from HasEvents

included

Methods included from KeyValueCoding

#get, #set

Methods included from PropertyOwner

included, #properties

Constructor Details

This class inherits a constructor from Metro::Model

Instance Attribute Details

#dampingObject

Amount of viscous damping to apply to the space. A value of 0.9 means that each body will lose 10% of it’s velocity per second. Defaults to 1. Like gravity can be overridden on a per body basis.



36
# File 'lib/metro/models/ui/space.rb', line 36

property :damping, default: 0.5

#deltaObject

The amount of time the space should be stepped. This step value is multiplied by the #sampling_per_update value.



48
# File 'lib/metro/models/ui/space.rb', line 48

property :delta, default: (1.0/60.0)

#gravitational_forcesObject

The amount of gravitationl force to apply to bodies within the space. This is by default a force at the center of the object applied downward.



53
54
# File 'lib/metro/models/ui/space.rb', line 53

property :gravitational_forces, type: :array,
default: [ CP::Vec2.new(0,1000), CP::Vec2.new(0,0) ]

#sampling_per_updateObject

Each update cycle the space will perform a number of steps equal to this value. The higher the value the better the resolution will be for collisions between objects, the lower the value the sloppier the resolution will be for collisions.



43
# File 'lib/metro/models/ui/space.rb', line 43

property :sampling_per_update, default: 6

#spaceObject (readonly)

Access to the raw Chimpmunk Space object



103
104
105
# File 'lib/metro/models/ui/space.rb', line 103

def space
  @space
end

Instance Method Details

#add_object(object) ⇒ Object

Add a single object to the space. This object will have a reference stored here and it’s body and shape added to the space so that it collide with other objects added to the space.

Parameters:

  • object (Object<#body,#shape>)

    add a new object to the space. The object has a ‘body` and a `shape`.



63
64
65
66
67
# File 'lib/metro/models/ui/space.rb', line 63

def add_object(object)
  space_objects.push(object)
  space.add_body object.body
  space.add_shape object.shape
end

#add_objects(objects) ⇒ Object

Add multiple objects to the space.

See Also:



81
82
83
# File 'lib/metro/models/ui/space.rb', line 81

def add_objects(objects)
  Array(objects).each {|object| add_object(object) }
end

#apply_gravity_to(objects) ⇒ Object

Apply gravity to the specified objects.



146
147
148
# File 'lib/metro/models/ui/space.rb', line 146

def apply_gravity_to(objects)
  objects.each {|object| object.body.apply_force *gravitational_forces }
end

#clean_upObject

This method needs to be called each update loop. This will reset all the forces on the existing objects. This essentially keeps them from accelerating out of control. It will also rebuild the shape positioning for collisions. In a static frame, the level does not scroll, the rebuiling is not necessary, but for levels where it moves this is important.



120
121
122
123
# File 'lib/metro/models/ui/space.rb', line 120

def clean_up
  space_objects.each {|object| object.body.reset_forces }
  space.rehash_static
end

#collision_between(first, second, &block) ⇒ Object

When the first shape collides with the second shape perform the following block of code.



87
88
89
# File 'lib/metro/models/ui/space.rb', line 87

def collision_between(first,second,&block)
  space.add_collision_func(first,second,&block)
end

#gravity_affects(object) ⇒ Object

Note:

for the object to be affected by gravity it still needs to be added to the space first.

This method allows the space to declare which objects are effected by gravity during their time within the space.



97
98
99
# File 'lib/metro/models/ui/space.rb', line 97

def gravity_affects(object)
  victims_of_gravity.push object
end

#remove_object(object) ⇒ Object

Remove a single object from the space. This object will remove the reference stored within the space as well as removing the body and shape that was added to the space.



73
74
75
76
77
# File 'lib/metro/models/ui/space.rb', line 73

def remove_object(object)
  space_objects.delete(object)
  space.remove_body(object.body)
  space.remove_shape(object.shape)
end

#showObject



125
126
127
128
# File 'lib/metro/models/ui/space.rb', line 125

def show
  @space = CP::Space.new
  @space.damping = damping
end

#space_objectsArray<Object>

Returns a list of objects currently mantained by the space.

Returns:

  • (Array<Object>)

    a list of objects currently mantained by the space.



136
137
138
# File 'lib/metro/models/ui/space.rb', line 136

def space_objects
  @space_objects ||= []
end

#stepObject

This method needs to be called each update loop. This will update and move all the objects currently within the space and start the resolution of collisions.



109
110
111
# File 'lib/metro/models/ui/space.rb', line 109

def step
  sampling_per_update.to_i.times { space.step(delta) }
end

#updateObject



130
131
132
# File 'lib/metro/models/ui/space.rb', line 130

def update
  apply_gravity_to victims_of_gravity
end

#victims_of_gravityArray<Object>

Returns all of the objects that are affected by gravity.

Returns:

  • (Array<Object>)

    all of the objects that are affected by gravity



141
142
143
# File 'lib/metro/models/ui/space.rb', line 141

def victims_of_gravity
  @victims_of_gravity ||= []
end