Class: Chingu::GameStateManager

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

Constructor Details

#initializeGameStateManager

Returns a new instance of GameStateManager.



47
48
49
50
51
52
53
# File 'lib/chingu/game_state_manager.rb', line 47

def initialize
  @inside_state = nil
  @game_states = []
  @transitional_game_state = nil
  @transitional_game_state_options = {}
  @previous_game_state = nil
end

Instance Attribute Details

#inside_stateObject

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.



233
234
235
# File 'lib/chingu/game_state_manager.rb', line 233

def button_down(id)
  current_game_state.button_down(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.



243
244
245
# File 'lib/chingu/game_state_manager.rb', line 243

def button_up(id)
  current_game_state.button_up(id)  if current_game_state
end

#clear_game_statesObject Also known as: clear

Remove all game states from stack. Shortcut: “clear”



212
213
214
215
# File 'lib/chingu/game_state_manager.rb', line 212

def clear_game_states
  @game_states.clear
  self.inside_state = nil
end

#current_game_stateObject Also known as: current

Gets the currently active gamestate (top of stack)



58
59
60
# File 'lib/chingu/game_state_manager.rb', line 58

def current_game_state
  @game_states.last
end

#drawObject

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.



263
264
265
# File 'lib/chingu/game_state_manager.rb', line 263

def draw
  current_game_state.draw           if current_game_state
end

#game_statesObject

Returns all gamestates with currenlty active game state on top.



66
67
68
# File 'lib/chingu/game_state_manager.rb', line 66

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.



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/chingu/game_state_manager.rb', line 175

def pop_game_state(options = {})
  options = {:setup => true, :finalize => true, :transitional => true}.merge(options)
  
  #
  # Give the soon-to-be-disabled state a chance to clean up by calling finalize() on it.
  #
  @previous_game_state = current_game_state
  current_game_state.finalize    if current_game_state.respond_to?(:finalize) && options[:finalize]

  #
  # Activate the game state "bellow" current one with a simple Array.pop
  #
  @game_states.pop
    
  # Call setup on the new current state
  current_game_state.setup       if current_game_state.respond_to?(:setup) && options[:setup]
  
  if @transitional_game_state && options[: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)
    self.switch_game_state(transitional_game_state, :transitional => false)
  end
  self.inside_state = current_game_state
end

#pop_until_game_state(new_state) ⇒ Object

Pops through all game states until matching a given game state



221
222
223
224
225
# File 'lib/chingu/game_state_manager.rb', line 221

def pop_until_game_state(new_state)
  while (state = @game_states.pop)
    break if state == new_state
  end
end

#previous_game_stateObject Also known as: previous

Returns the previous game state. Shortcut: “previous”



204
205
206
# File 'lib/chingu/game_state_manager.rb', line 204

def previous_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.



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/chingu/game_state_manager.rb', line 141

def push_game_state(state, options = {})
  options = {:setup => true, :finalize => true, :transitional => true}.merge(options)

  new_state = game_state_instance(state)
        
  if new_state
    # Call setup
    new_state.setup               if new_state.respond_to?(:setup) && options[:setup]
    
    # Make sure the game state knows about the manager
    new_state.game_state_manager = self
    
    # Give the soon-to-be-disabled state a chance to clean up by calling finalize() on it.
    @previous_game_state = current_game_state
    current_game_state.finalize   if current_game_state.respond_to?(:finalize) && options[:finalize]
    
    if @transitional_game_state && options[: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)
      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
    self.inside_state = current_game_state
  end
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.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/chingu/game_state_manager.rb', line 102

def switch_game_state(state, options = {})
  options = {:setup => true, :finalize => true, :transitional => true}.merge(options)

  new_state = game_state_instance(state)
  
  if new_state
    # Make sure the game state knows about the manager
    new_state.game_state_manager = self
    
    
    # Give the soon-to-be-disabled state a chance to clean up by calling finalize() on it.
    @previous_game_state = current_game_state
    current_game_state.finalize   if current_game_state.respond_to?(:finalize) && options[:finalize]
    
    # Call setup
    new_state.setup               if new_state.respond_to?(:setup) && options[:setup]
    
    if @transitional_game_state && options[:transitional]
      # If we have a transitional, switch to that instead, with new_state as first argument
      transitional_game_state = @transitional_game_state.new(new_state, @transitional_game_state_options)
      self.switch_game_state(transitional_game_state, :transitional => false)
    else
      if current_game_state.nil?
        @game_states << new_state
      else
        # Replace last (active) state with new one
        @game_states[-1] = new_state
      end
    end
    self.inside_state = current_game_state
  end
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.



92
93
94
95
# File 'lib/chingu/game_state_manager.rb', line 92

def transitional_game_state(game_state, options = {})
  @transitional_game_state = game_state
  @transitional_game_state_options = options
end

#updateObject

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.



253
254
255
# File 'lib/chingu/game_state_manager.rb', line 253

def update
  current_game_state.update         if current_game_state
end