Not logged inGosu Forums
Forum back to libgosu.org Help Search Register Login
Up Topic Gosu / Extending Gosu / Game state manager for Gosu (Gem available)
- By ippa Date 2009-08-19 11:08
So, I've been working on a framework for Gosu this summer, Chingu. It can be found @ http://github.com/ippa/chingu/tree/master
While Chingu the framework isn't release-ready just yet parts of it are.

One of those part is a basic but decently powerfull stack-based game state system which is usable even in very small games.
I've made it "stand alone" so it should it plugs nicely into any Gosu game.

INSTALL:
=======
gem sources -a http://gems.github.com
gem install ippa-chingu

BASIC USAGE:
===========
class Game < Gosu::Window
  attr_reader :font
  def initialize
    $window = super(800,600,false)
    # Create our game state manager and start out with State1
    @manager = Chingu::GameStateManager.new
    @manager.switch_game_state(State1)
  end
 
  def button_down(id)
    @manager.button_down(id)
  end
 
  def button_up(id)
    @manager.button_up(id)
  end

  def draw
     @manager.draw
  end
 
  def update
    @manager.update
  end
end

class State1 < Chingu::GameState
  def setup
    @spinner = ["|", "/", "-", "\\", "|", "/", "-", "\\"]
    @spinner_index = 0.0
  end
 
  def update(dt)
    @spinner_index += 0.1
    @spinner_index = 0    if @spinner_index >= @spinner.size
  end
 
  def draw
    $window.font.draw("Inside State1: #{@spinner[@spinner_index.to_i]}", 100, 100, 0)
  end
end

DOCS:
=====
A GameState is just a class with the following instance methods:
  * setup() - called each time the game state becomes active.
  * button_down(id) - Called when a button is down
  * button_up(id) - Called when a button is released
  * update() - just as in your normal game loop, put your game logic here.
  * draw() - just as in your normal game loop, put your screen manipulation here.
  * finalize() - called when a game state de-activated (for example by pushing a new one on top with push_game_state)

GameStateManager has the following public instance methods to work with states:

  * push_game_state(state) - adds a new gamestate on top of the stack, which then becomes the active one
  * pop_game_state - removes active gamestate and activates the previous one
  * switch_game_state(state) - replaces current game state with a new one
  * current_game_state - returns the current game state
  * previous_game_state - returns the previous game state (useful for pausing and dialog boxes, see example4.rb)
  * pop_until_game_state(state) - pop game states until given state is found
  * clear_game_states - removes all game states from stack

There's some more documentation @ http://rdoc.info/rdoc/ippa/chingu/blob/407e5bb9b3cead4d02d7d07c1da1d0a2fad8cbfe/Chingu/GameStateManager.html
Chingu  docs @ http://rdoc.info/projects/ippa/chingu

MORE CODE:
===========
If you install the gem you get an examples-dir:

  * example4.rb shows Chingu / game states
  * example5.rb shows game states with Only Gosu.

I'm using this in 2 games, and those games have been a driving force of getting a decent system in place.

While Chingu very much still is work in progress I feedback is always cool, on the game state system and in Chingu in general. I'll probably make a full Chingu-release-statement within a couple of weeks once it has matured and good documentation is in place.
- By Dahrkael Date 2009-08-19 11:56
Cool :o is like the system im using for my project, stacking the updates and button_

is possible to get this with fades? will be awesome
- By ippa Date 2009-08-19 13:17
That's an important thing on my list, transitions. I haven't yet decided the best way to do it. Maybe easiest solved with just a game state.

Something like: (this is not working code)

class FadeTo < Chingu::GameState
   def initialize(gamestate)
     @gamestate = gamestate
  end

   def draw
       if @fading_out
          previous_game_state.draw   # draw previous screen
          $window.draw_quad              # darken with a transparent layover
      else
          @gamestate.update  # call update once not to progress the gameplay too much
          @gamestate.draw     # draw
          $window.draw_quad              # start dark, lighten with trans layover
      end
   end

  def finalize
       $window.manager.switch_game_state(@gamestate)
  end
end

Then in Menu game state:
@manager.push_game_state(FadeTo.new(Play))

I'll post something working when I have it.
- By psadda Date 2009-08-20 17:05
ippa, I implemented a FadeTo GameState in my Gosu GUI Library. You should check it out. You can use the code if you want. (It's open source, MIT License)
- By ippa Date 2009-08-20 20:09
Hey psadda .. I tracked down your code in state.rb :). Nice lib, though it would be cool if you don't have to inherit from GGLib::GUIWindow to use the widgets etc. Another thing, the examples needs to be moved around to find "../gglib.rb". Looking forward to your full 2.0 release!

I made my own fade implementation from scratch:

http://github.com/ippa/chingu/blob/80ed4dfcbbaffd8e1c60fe69a444b3e01ac6b615/examples/example6.rb

That's a full example, the actual fade logic is only 35 lines and fades between current state and a state of coders choice.
- By ? Date 2009-08-21 01:33
I could never figure out how to get transparency with $window.draw_quad. How did you do that?
- By psadda Date 2009-08-21 01:34
That was me by the way. ^^
- By ippa Date 2009-08-21 05:27
@psadda: draw a quad over the whole screen, color black, start with full 255 transperency, "fade" to 0 transperency.
- By ippa Date 2009-08-21 17:05
Been working alot on the state system today.

First off I've bundled 2 premade game states with Chingu, FadeTo and Pause. FadeTo fades between the current game state and a new one. Pause pauses any game state with a nice shading of the scene. They'll work with pure gosu + the above game state manager.

Since FadeTo gives a game such a nice touch, it's probably something you want to use throughout a certain game. Therefore:

  @manager.transitional_game_state(Chingu::GameStates::FadeTo)

Whenever a game state is pushed, popped or switched, FadeTo will be inserted in between. FadeTo is just another GameState so it's easy to make some own effect you want to have. Your code has to switch to the new game state though, preferable with ":transition => false" not to create an eternal loop :p.

See updated http://github.com/ippa/chingu/blob/fdad865c4bdb20f6461a967f71f0879a2c8fbeb6/examples/example6.rb for an example.

Cheers.
- By erisdiscord Date 2009-09-14 06:51
Perhaps you should create another GameState subclass as part of your library—something like, er, Transition—and have that class implement all the magic like switching to the next state automatically. Transitional states such as FadeTo, obviously, would inherit from that.

Oh boy, when the alert popup told me I was replying to a post older than 24 hours, I didn't realise it was from last month. Sorry, I'll pay more attention next time!
Up Topic Gosu / Extending Gosu / Game state manager for Gosu (Gem available)

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill