Class: Chingu::GameStateManager
- Inherits:
-
Object
- Object
- Chingu::GameStateManager
- Defined in:
- lib/chingu/game_state_manager.rb
Overview
GameStateManger is responsible for keeping track of game states with a simple pop/push stack.
More about the concept of states in games: gamedevgeek.com/tutorials/managing-game-states-in-c/ www.gamedev.net/community/forums/topic.asp?topic_id=477320
Chingu::Window automatically creates a @game_state_manager and makes it accessible in our game loop. By default the game loop calls update, draw, button_up(id) and button_down(id) on the active state.
Chingu Examples
Enter a new game state, Level, don't call finalize() on the game state we're leaving.
push_game_state(Level, :finalize => false)
Return to the previous game state, don't call setup() on it when it becomes active.
pop_game_state(:setup => false)
If you want to use Chingus GameStateManager without Chingu::Window, see example5.rb
Instance Attribute Summary collapse
-
#inside_state ⇒ Object
Returns the value of attribute inside_state.
Instance Method Summary collapse
-
#button_down(id) ⇒ Object
This method should be called from button_down(id) inside your main loop.
-
#button_up(id) ⇒ Object
This method should be called from button_up(id) inside your main loop.
-
#clear_game_states ⇒ Object
(also: #clear)
Remove all game states from stack.
-
#current_game_state ⇒ Object
(also: #current)
Gets the currently active gamestate (top of stack).
-
#draw ⇒ Object
This method should be called from draw() inside your main loop.
-
#game_states ⇒ Object
Returns all gamestates with currenlty active game state on top.
-
#initialize ⇒ GameStateManager
constructor
A new instance of GameStateManager.
-
#pop_game_state(options = {}) ⇒ Object
(also: #pop)
Pops a state off the game state-stack, activating the previous one.
-
#pop_until_game_state(new_state, options = {}) ⇒ Object
Pops through all game states until matching a given game state (takes either a class or instance to match).
-
#previous_game_state ⇒ Object
(also: #previous)
Returns the previous game state.
-
#push_game_state(state, options = {}) ⇒ Object
(also: #push)
Adds a state to the game state-stack and activates it.
-
#switch_game_state(state, options = {}) ⇒ Object
(also: #switch)
Switch to a given game state, replacing the current active one.
-
#transitional_game_state(game_state, options = {}) ⇒ Object
Sets a game state to be called between the old and the new game state whenever a game state is switched,pushed or popped.
-
#update(options = {}) ⇒ Object
This method should be called from update() inside your main loop.
Constructor Details
#initialize ⇒ GameStateManager
Returns a new instance of GameStateManager.
47 48 49 50 51 52 |
# File 'lib/chingu/game_state_manager.rb', line 47 def initialize @inside_state = nil @game_states = [] @transitional_game_state = nil @transitional_game_state_options = {} end |
Instance Attribute Details
#inside_state ⇒ Object
Returns the value of attribute inside_state
45 46 47 |
# File 'lib/chingu/game_state_manager.rb', line 45 def inside_state @inside_state end |
Instance Method Details
#button_down(id) ⇒ Object
This method should be called from button_down(id) inside your main loop. Enables the game state manager to call button_down(id) on active game state.
If you're using Chingu::Window instead of Gosu::Window this will automaticly be called.
227 228 229 |
# File 'lib/chingu/game_state_manager.rb', line 227 def (id) current_game_state.(id) if current_game_state end |
#button_up(id) ⇒ Object
This method should be called from button_up(id) inside your main loop. Enables the game state manager to call button_up(id) on active game state.
If you're using Chingu::Window instead of Gosu::Window this will automaticly be called.
237 238 239 |
# File 'lib/chingu/game_state_manager.rb', line 237 def (id) current_game_state.(id) if current_game_state end |
#clear_game_states ⇒ Object Also known as: clear
Remove all game states from stack. Shortcut: “clear”
199 200 201 202 |
# File 'lib/chingu/game_state_manager.rb', line 199 def clear_game_states @game_states.clear self.inside_state = nil end |
#current_game_state ⇒ Object Also known as: current
Gets the currently active gamestate (top of stack)
57 58 59 |
# File 'lib/chingu/game_state_manager.rb', line 57 def current_game_state @game_states.last end |
#draw ⇒ Object
This method should be called from draw() inside your main loop. Enables the game state manager to call update() on active game state.
If you're using Chingu::Window instead of Gosu::Window this will automaticly be called.
259 260 261 262 263 264 |
# File 'lib/chingu/game_state_manager.rb', line 259 def draw if current_game_state current_game_state.draw_trait current_game_state.draw end end |
#game_states ⇒ Object
Returns all gamestates with currenlty active game state on top.
65 66 67 |
# File 'lib/chingu/game_state_manager.rb', line 65 def game_states @game_states.reverse end |
#pop_game_state(options = {}) ⇒ Object Also known as: pop
Pops a state off the game state-stack, activating the previous one. By default setup() is called on the game state that becomes active. .. and finalize() is called on the game state we're leaving.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/chingu/game_state_manager.rb', line 156 def pop_game_state( = {}) = {:setup => true, :finalize => true, :transitional => true}.merge() # # Give the soon-to-be-disabled state a chance to clean up by calling finalize() on it. # current_game_state.finalize if current_game_state.respond_to?(:finalize) && [:finalize] # # Activate the game state "bellow" current one with a simple Array.pop # @game_states.pop # So BasicGameObject#create connects object to new state in its setup() # Is this doubled in GameState.initialize() ? self.inside_state = current_game_state # Call setup on the new current state current_game_state.setup if current_game_state.respond_to?(:setup) && [:setup] if @transitional_game_state && [:transitional] # If we have a transitional, push that instead, with new_state as first argument transitional_game_state = @transitional_game_state.new(current_game_state, @transitional_game_state_options) transitional_game_state.game_state_manager = self self.push_game_state(transitional_game_state, :transitional => false) end ## MOVED: self.inside_state = current_game_state self.inside_state = nil # no longer 'inside' (as in within initialize() etc) a game state end |
#pop_until_game_state(new_state, options = {}) ⇒ Object
Pops through all game states until matching a given game state (takes either a class or instance to match).
208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/chingu/game_state_manager.rb', line 208 def pop_until_game_state(new_state, = {}) if new_state.is_a? Class raise ArgumentError, "No state of given class is on the stack" unless @game_states.any? {|s| s.is_a? new_state } pop_game_state() until current_game_state.is_a? new_state else raise ArgumentError, "State is not on the stack" unless @game_states.include? new_state pop_game_state() until current_game_state == new_state end end |
#previous_game_state ⇒ Object Also known as: previous
Returns the previous game state. Shortcut: “previous”
191 192 193 |
# File 'lib/chingu/game_state_manager.rb', line 191 def previous_game_state current_game_state.previous_game_state end |
#push_game_state(state, options = {}) ⇒ Object Also known as: push
Adds a state to the game state-stack and activates it. By default setup() is called on the new game state .. and finalize() is called on the game state we're leaving.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/chingu/game_state_manager.rb', line 115 def push_game_state(state, = {}) = {:setup => true, :finalize => true, :transitional => true}.merge() new_state = game_state_instance(state) if new_state # So BasicGameObject#create connects object to new state in its setup() self.inside_state = new_state # Make sure the game state knows about the manager # Is this doubled in GameState.initialize() ? new_state.game_state_manager = self # Call setup new_state.setup if new_state.respond_to?(:setup) && [:setup] # Give the soon-to-be-disabled state a chance to clean up by calling finalize() on it. current_game_state.finalize if current_game_state.respond_to?(:finalize) && [:finalize] if @transitional_game_state && [:transitional] # If we have a transitional, push that instead, with new_state as first argument transitional_game_state = @transitional_game_state.new(new_state, @transitional_game_state_options) transitional_game_state.game_state_manager = self self.push_game_state(transitional_game_state, :transitional => false) else # Push new state on top of stack and therefore making it active @game_states.push(new_state) end ## MOVED: self.inside_state = current_game_state end self.inside_state = nil # no longer 'inside' (as in within initialize() etc) a game state end |
#switch_game_state(state, options = {}) ⇒ Object Also known as: switch
Switch to a given game state, replacing the current active one. By default setup() is called on the game state we're switching to. .. and finalize() is called on the game state we're switching from.
101 102 103 104 105 106 107 |
# File 'lib/chingu/game_state_manager.rb', line 101 def switch_game_state(state, = {}) = {:setup => true, :finalize => true, :transitional => true}.merge!() # Don't setup or finalize the underlying state, since it never becomes active. pop_game_state(.merge(:setup => false)) push_game_state(state, .merge(:finalize => false)) end |
#transitional_game_state(game_state, options = {}) ⇒ Object
Sets a game state to be called between the old and the new game state whenever a game state is switched,pushed or popped.
The transitional game state is responsible for switching to the “new game state”. It should do so with “:transitional => false” not to create an infinite loop.
The new game state is the first argument to the transitional game states initialize().
Example:
transitional_game_state(FadeIn)
push_game_state(Level2)
would in practice become:
push_game_state(FadeIn.new(Level2))
This would be the case for every game state change until the transitional game state is removed:
transitional_game_state(nil) # or false
Very useful for fading effect between scenes.
91 92 93 94 |
# File 'lib/chingu/game_state_manager.rb', line 91 def transitional_game_state(game_state, = {}) @transitional_game_state = game_state @transitional_game_state_options = end |
#update(options = {}) ⇒ Object
This method should be called from update() inside your main loop. Enables the game state manager to call update() on active game state.
If you're using Chingu::Window instead of Gosu::Window this will automaticly be called.
247 248 249 250 251 |
# File 'lib/chingu/game_state_manager.rb', line 247 def update( = {}) puts current_game_state.to_s if [:debug] current_game_state.update_trait if current_game_state current_game_state.update if current_game_state end |