Class: Metro::Scene
- Inherits:
-
Object
- Object
- Metro::Scene
- Includes:
- Draws, HasAnimations, HasEvents, SceneView, Units
- Defined in:
- lib/metro/scene.rb
Overview
A scene is a basic unit of a game. Within a scene you define a number of methods that handle the initial setup, event configuration, logic updating, and drawing.
A fair number of private methods within Scene are prefaced with an underscore. These methods often call non-underscored methods within those methods. This allows for scene to configure or perform some functionality, while providing an interface so that every subclass does not have to constantly call ‘super`.
Direct Known Subclasses
Constant Summary
Constants included from Units
Instance Attribute Summary collapse
-
#window ⇒ Object
The window is the main instance of the game.
Class Method Summary collapse
-
.after(ticks, &block) ⇒ Object
Allow the definition of a updater that will be executed when the scene starts.
-
.after_intervals ⇒ Object
The class defined updaters which will be converted to instance updaters when the scene has started.
-
.hierarchy ⇒ Object
An array of all the scene names of all the ancestor scenes.
-
.inherited(base) ⇒ Object
Captures all classes that subclass Scene.
-
.metro_name ⇒ Object
A common name that can be used through the system as a common identifier.
-
.scene_name(scene_name = nil) ⇒ Object
Allows you to set or retrieve the scene name for the Scene.
-
.scenes ⇒ Object
All subclasses of Scene, this should be all the defined scenes within the game.
Instance Method Summary collapse
-
#_prepare_transition(new_scene) ⇒ Object
Before a scene is transitioned away from to a new scene, this private method is here to allow for any housekeeping or other work that needs to be done before calling the subclasses implementation of ‘prepare_transition`.
-
#actor(actor_or_actor_name) ⇒ Object
When an actor is defined, through the class method ‘draw` a getter and setter method is defined.
- #add_actors_to_scene ⇒ Object
-
#after(ticks, &block) ⇒ Object
Perform an operation after the specified interval.
-
#after_initialize ⇒ Object
As Scene does a lot of work for you with regarding to setting up content, it is best not to override #initialize and instead define an #after_initialize method within the subclasses of Scene.
-
#base_draw ⇒ Object
The ‘base_draw` method is called by the Game Window.
-
#base_update ⇒ Object
The ‘base_update` method is called by the Game Window.
-
#draw ⇒ Object
This is called after every #update and when the OS wants the window to repaint itself.
-
#drawers ⇒ Object
The objects that need to be drawn with every draw cycle.
-
#enqueue(updater) ⇒ Object
Enqueue will add an updater to the list of updaters that are run initially when update is called.
-
#initialize ⇒ Scene
constructor
Setups up the Actors for the Scene based on the ModelFactories that have been defined.
-
#notification(event, sender = nil) ⇒ Object
Post a custom notification event.
-
#prepare_transition_from(old_scene) ⇒ Object
Before a scene is transitioned to it is called with the previous scene.
-
#prepare_transition_to(new_scene) ⇒ Object
Before a scene is transitioned away from to a new scene, this method is called to allow for the scene to complete any tasks, stop any actions, or pass any information from the existing scene to the scene that is about to replace it.
-
#register_actor(actor_factory) ⇒ Object
Registering an actor involves setting up the actor within the window, adding them to the list of things that need to be drawn and then registering any eventst that they might have.
-
#register_actors! ⇒ Object
Register all the actors that were defined for this scene.
- #register_after_intervals! ⇒ Object
-
#register_animations! ⇒ Object
Register all the animations that were defined for this scene.
-
#register_events! ⇒ Object
Register all the events that were defined for this scene.
-
#register_events_for_target(target, events) ⇒ Object
Helper method that is used internally to setup the events for the specified target.
-
#scene_name ⇒ Object
Allows you to set or retrieve the scene name for the Scene.
-
#show ⇒ Object
This method is called right after the scene has been adopted by the window.
-
#state ⇒ Object
The event state manager is configured through the #events method, which stores all the gamepad and keyboard events defined.
-
#to_hash ⇒ Object
A Scene represented as a hash currently only contains the drawers.
-
#to_s ⇒ Object
The string representation of a scene, this is used for debugging.
-
#transition_to(scene_or_scene_name, options = {}) ⇒ Object
‘transition_to` performs the work of transitioning this scene to another scene.
-
#update ⇒ Object
This is called every update interval while the window is being shown.
-
#updaters ⇒ Object
The objects that need to be executed on every update.
Methods included from SceneView
included, #save_view, #view, #view_content, #view_name
Methods included from HasAnimations
Methods included from HasEvents
Methods included from Draws
Constructor Details
#initialize ⇒ Scene
this method should not be overriden, otherwise the actors will perish!
Setups up the Actors for the Scene based on the ModelFactories that have been defined.
166 167 168 169 |
# File 'lib/metro/scene.rb', line 166 def initialize add_actors_to_scene after_initialize end |
Instance Attribute Details
#window ⇒ Object
The window is the main instance of the game. Using window can access a lot of underlying Metro::Window, a subclass of Gosu::Window, that the Scene class is obfuscating.
187 188 189 |
# File 'lib/metro/scene.rb', line 187 def window @window end |
Class Method Details
.after(ticks, &block) ⇒ Object
Allow the definition of a updater that will be executed when the scene starts.
132 133 134 |
# File 'lib/metro/scene.rb', line 132 def self.after(ticks,&block) after_intervals.push AfterIntervalFactory.new ticks, &block end |
.after_intervals ⇒ Object
The class defined updaters which will be converted to instance updaters when the scene has started.
357 358 359 |
# File 'lib/metro/scene.rb', line 357 def self.after_intervals @after_intervals ||= [] end |
.hierarchy ⇒ Object
Returns an array of all the scene names of all the ancestor scenes.
299 300 301 |
# File 'lib/metro/scene.rb', line 299 def self.hierarchy ancestors.find_all {|a| a.respond_to? :metro_name }.map(&:metro_name) end |
.inherited(base) ⇒ Object
Captures all classes that subclass Scene.
330 331 332 333 |
# File 'lib/metro/scene.rb', line 330 def self.inherited(base) scenes << base.to_s Scenes.add(base) end |
.metro_name ⇒ Object
Returns a common name that can be used through the system as a common identifier.
292 293 294 |
# File 'lib/metro/scene.rb', line 292 def self.metro_name scene_name end |
.scene_name(scene_name = nil) ⇒ Object
Allows you to set or retrieve the scene name for the Scene.
277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/metro/scene.rb', line 277 def self.scene_name(scene_name=nil) @scene_name ||= begin if to_s == "Metro::Scene" to_s.underscore else to_s.gsub(/_?Scene$/i,'').underscore end end scene_name ? @scene_name = scene_name.to_s : @scene_name end |
.scenes ⇒ Object
All subclasses of Scene, this should be all the defined scenes within the game.
340 341 342 |
# File 'lib/metro/scene.rb', line 340 def self.scenes @scenes ||= [] end |
Instance Method Details
#_prepare_transition(new_scene) ⇒ Object
Before a scene is transitioned away from to a new scene, this private method is here to allow for any housekeeping or other work that needs to be done before calling the subclasses implementation of ‘prepare_transition`.
424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'lib/metro/scene.rb', line 424 def _prepare_transition(new_scene) log.debug "Preparing to transition from scene #{self} to #{new_scene}" new_scene.class.actors.find_all {|actor_factory| actor_factory.load_from_previous_scene? }.each do |actor_factory| new_actor = new_scene.actor(actor_factory.name) current_actor = actor(actor_factory.name) new_actor._load current_actor._save end prepare_transition_to(new_scene) new_scene.prepare_transition_from(self) end |
#actor(actor_or_actor_name) ⇒ Object
When an actor is defined, through the class method ‘draw` a getter and setter method is defined. However, it is a better interface internally not to rely heavily on send and have this small amount of obfuscation in the event that this needs to change.
91 92 93 94 95 96 97 |
# File 'lib/metro/scene.rb', line 91 def actor(actor_or_actor_name) if actor_or_actor_name.is_a? String or actor_or_actor_name.is_a? Symbol send(actor_or_actor_name) else actor_or_actor_name end end |
#add_actors_to_scene ⇒ Object
171 172 173 174 175 176 177 |
# File 'lib/metro/scene.rb', line 171 def add_actors_to_scene self.class.actors.each do |scene_actor| actor_instance = scene_actor.create actor_instance.scene = self send "#{scene_actor.name}=", actor_instance end end |
#after(ticks, &block) ⇒ Object
Perform an operation after the specified interval.
class ExampleScene
draws :player
def update
if player.is_dead?
after 2.seconds do
transition_to :game_over
end
end
end
end
153 154 155 156 157 |
# File 'lib/metro/scene.rb', line 153 def after(ticks,&block) tick = OnUpdateOperation.new interval: ticks, context: self tick.on_complete(&block) enqueue tick end |
#after_initialize ⇒ Object
This method should be implemented in the Scene subclass.
As Scene does a lot of work for you with regarding to setting up content, it is best not to override #initialize and instead define an #after_initialize method within the subclasses of Scene.
34 |
# File 'lib/metro/scene.rb', line 34 def after_initialize ; end |
#base_draw ⇒ Object
The ‘base_draw` method is called by the Game Window. This is to allow for any special drawing needs to be handled before calling the traditional `draw` method defined in the subclassed Scene.
394 395 396 397 |
# File 'lib/metro/scene.rb', line 394 def base_draw drawers.each { |drawer| drawer.draw } draw end |
#base_update ⇒ Object
The ‘base_update` method is called by the Game Window. This is to allow for any special update needs to be handled before calling the traditional `update` method defined in the subclassed Scene.
375 376 377 378 379 |
# File 'lib/metro/scene.rb', line 375 def base_update updaters.each { |updater| updater.update } update updaters.reject! { |updater| updater.completed? } end |
#draw ⇒ Object
This method should be implemented in the Scene subclass.
This is called after every #update and when the OS wants the window to repaint itself.
56 |
# File 'lib/metro/scene.rb', line 56 def draw ; end |
#drawers ⇒ Object
The objects that need to be drawn with every draw cycle. These objects are traditionally the model objects, like the actors defined within the scene.
385 386 387 |
# File 'lib/metro/scene.rb', line 385 def drawers @drawers ||= [] end |
#enqueue(updater) ⇒ Object
Enqueue will add an updater to the list of updaters that are run initially when update is called. An updater is any object that can respond to #update. This is used for animations.
349 350 351 |
# File 'lib/metro/scene.rb', line 349 def enqueue(updater) updaters.push(updater) end |
#notification(event, sender = nil) ⇒ Object
Post a custom notification event. This will trigger an event for all the objects that are registered for notification with the current state.
103 104 105 106 |
# File 'lib/metro/scene.rb', line 103 def notification(event,sender=nil) sender = sender || UnknownSender state.fire_events_for_notification(event,sender) end |
#prepare_transition_from(old_scene) ⇒ Object
This method should be implemented in the Scene subclass.
Before a scene is transitioned to it is called with the previous scene. This allows for the new scene to retrieve any data from the previous scene to assist with the layout of the current scene.
80 |
# File 'lib/metro/scene.rb', line 80 def prepare_transition_from(old_scene) ; end |
#prepare_transition_to(new_scene) ⇒ Object
This method should be implemented in the Scene subclass.
Before a scene is transitioned away from to a new scene, this method is called to allow for the scene to complete any tasks, stop any actions, or pass any information from the existing scene to the scene that is about to replace it.
68 |
# File 'lib/metro/scene.rb', line 68 def prepare_transition_to(new_scene) ; end |
#register_actor(actor_factory) ⇒ Object
Registering an actor involves setting up the actor within the window, adding them to the list of things that need to be drawn and then registering any eventst that they might have.
242 243 244 245 246 247 248 249 250 251 |
# File 'lib/metro/scene.rb', line 242 def register_actor(actor_factory) registering_actor = actor(actor_factory.name) registering_actor.window = window registering_actor.show drawers.push(registering_actor) updaters.push(registering_actor) register_events_for_target(registering_actor,registering_actor.class.events) end |
#register_actors! ⇒ Object
Register all the actors that were defined for this scene.
218 219 220 |
# File 'lib/metro/scene.rb', line 218 def register_actors! self.class.actors.each { |actor| register_actor(actor) } end |
#register_after_intervals! ⇒ Object
231 232 233 234 235 |
# File 'lib/metro/scene.rb', line 231 def register_after_intervals! self.class.after_intervals.each do |after_interval| after after_interval.ticks, &after_interval.block end end |
#register_animations! ⇒ Object
Register all the animations that were defined for this scene.
225 226 227 228 229 |
# File 'lib/metro/scene.rb', line 225 def register_animations! self.class.animations.each do |animation| animate animation.actor, animation., &animation.on_complete_block end end |
#register_events! ⇒ Object
Register all the events that were defined for this scene.
211 212 213 |
# File 'lib/metro/scene.rb', line 211 def register_events! register_events_for_target(self,self.class.events) end |
#register_events_for_target(target, events) ⇒ Object
Helper method that is used internally to setup the events for the specified target.
447 448 449 |
# File 'lib/metro/scene.rb', line 447 def register_events_for_target(target,events) state.add_events_for_target(target,events) end |
#scene_name ⇒ Object
Allows you to set or retrieve the scene name for the Scene.
316 317 318 |
# File 'lib/metro/scene.rb', line 316 def scene_name self.class.scene_name end |
#show ⇒ Object
This method should be implemented in the Scene subclass.
This method is called right after the scene has been adopted by the window
41 |
# File 'lib/metro/scene.rb', line 41 def show ; end |
#state ⇒ Object
The event state manager is configured through the #events method, which stores all the gamepad and keyboard events defined. By default a scene is placed in the default state and events that are added to this basic state.
458 459 460 |
# File 'lib/metro/scene.rb', line 458 def state @event_state_manager ||= EventStateManager.new end |
#to_hash ⇒ Object
A Scene represented as a hash currently only contains the drawers
467 468 469 470 471 472 473 474 |
# File 'lib/metro/scene.rb', line 467 def to_hash drawn = drawers.find_all{|draw| draw.saveable_to_view }.inject({}) do |hash,drawer| drawer_hash = drawer.to_hash hash.merge drawer_hash end drawn end |
#to_s ⇒ Object
Returns the string representation of a scene, this is used for debugging.
323 324 325 |
# File 'lib/metro/scene.rb', line 323 def to_s "[SCENE: #{self.class.scene_name}(#{self.class})]" end |
#transition_to(scene_or_scene_name, options = {}) ⇒ Object
‘transition_to` performs the work of transitioning this scene to another scene.
410 411 412 413 414 |
# File 'lib/metro/scene.rb', line 410 def transition_to(scene_or_scene_name, = {}) new_scene = Scenes.generate(scene_or_scene_name,) _prepare_transition(new_scene) window.scene = new_scene end |
#update ⇒ Object
This method should be implemented in the Scene subclass.
This is called every update interval while the window is being shown.
48 |
# File 'lib/metro/scene.rb', line 48 def update ; end |
#updaters ⇒ Object
The objects that need to be executed on every update. These objects are traditionally animations or window events for held pressed buttons. But can be any objects that responds to the method #update.
366 367 368 |
# File 'lib/metro/scene.rb', line 366 def updaters @updaters ||= [] end |