How to handle transitions between game states

Hi guys,

So I’ve worked through a few 2d java game programming tutorials on YouTube and learned a lot along the way. However, I’m still struggling to put all the pieces together in coherent fashion. One of the most challenging things is integrating everything into a game that transitions smoothly from state to state.

Lets say you have a game that starts at the title screen. You press start. The title screen fades to black, and a pre-level screen fades in, indicating the level and remaining lives. This screen fades to black, and the actual game fades in. You fall down a hole and die. The level fades out, the pre level screen fades back in, wash, rinse, repeat until you run out of lives, get a game over screen, and are booted back to the title.

How is this sort of transitioning best handled? How do the pros do it? These YouTube tuts don’t ever get in to that kind of stuff; it’s always about the lower level stuff. I did a tut that involved gameStates being held on a stack, but I’m not really sure how to use it, or if it’s even the right approach to use.

Any advice is appreciated!!!

lots of things possible here … but in your position i would use a very simple state-machine.

it can be very convenient. in pseudo code it could go like …

interface state
{
  void enter(state from);
  void update();
  void exit(state to);
}

so this thing could be used as something like [icode]TitleScreenState[/icode], [icode]MebuScreenState[/icode], [icode]LevelLoadingState[/icode] - in a [icode]Game[/icode] machine.

interface StateMachine
{
  void setState(state new_state);
  void update();
}

in the game-loop i would call [icode]while(!finished) machine.update()[/icode]
or maybe, with a slower rate, modify the world on enter/exit and use update to look for a new state.

on some event, like mouse-click, key-press, whatever i would call [icode]machine.setState(SaveMenu)[/icode] or something like this, from within the current state.

the fun part is the transition here.

class SomeMachine implements StateMachine
{
  state current;
  
  void setState( state new_state )
  {
    // not testing for null or current == new

    current.exit(new_state);

    state last = current;

    current = new_state;

    current.enter(last);
  }

  void update()
  {
    current.update();
  }
}

now everybody knows what’s going on.

… if you’d like to do something simple like fading in and out, i would track the current time at enter so i would know - during update how far i need to blend.


long fade_duration = 2000; // ms

long entered_at;
long fade_finished;

void enter( state from )
{
  entered_at = now();
  fade_finished = entered_at + fade_duration;
}

void update()
{
  float alpha = now() > fade_finished ? 1.0f : ( (double)now() - entered_at ) / fade_duration;
  // (value - min)/(max - min)
  [...]
}

maybe add some clamping(0.0, 1.0) but it should actually work :wink:

now the annoying part about this is, once a state exited, it’s not updated anymore - which cannot be used to create a fade-out effect.
yet, when exiting a state one could move it to a active list, which is updated along with the current state - until the state decides to die by itself. - or, one could create a new state which is blending two other states until one remains and so on.

alot ideas possible here.

state machines are way more complex, this is just a simple construct to help organize code.



o/

Hi

Maybe my schema and my short explanation can help you:

I use the Fettle API, it’s used in Candy Crush too.

gouessej: Sorry man, that’s way over my head.

basil_: I’m going to play around with this and see if I can successfully implement it. I’ll post any questions I have as I work my way through it. Thanks!

Hey,

So I went with something even simpler than using a StateMachine. I just made each stage of the game inherit from a class called GameState:

class Level extends GameState{
   //details
}
class TitleScreen extends GameState{
   //details
}

I have a unique instance of each GameState in the main Game class:

class Game extends Canvas implements Runnable{
   private Level level;
   private TitleScreen titleScreen;
   
   private GameState gs;  
   
   public Game(){
      level = new Level();
      titleScreen = new TitleScreen();
      
      gs = titleScreen;
   }
}

in Game.update() I have something like this:


gs.update();

if (gs.checkTransitionReady()) {
if (gs instanceof Title) {
	gs.reset();
	gs = transition;
	transition.setNextGameState(level);
	return;
}

if (gs instanceof Level) {
	gs.reset();
	gs = transition;

	if (player.getHud().getLives() > 0) {
		transition.setNextGameState(level);
		return;
	}

	transition.setNextGameState(gameOver);
	return;
}
			
if(gs instanceof GameOver){
	gs.reset();
	gs = transition;
	transition.setNextGameState(titleScreen);
	player.getHud().addToLives(3);
	return;
}

if (gs instanceof Transition) {
	gs.reset();
	gs = transition.getNextGameState();
	return;
}

Transition is a GameState subclass that serves the same purpose as a fade to black, but it is its own GameState. So each GameState that isn’t an instance of Transition will always load the next GameState to play after transition, and will always have transition as its next GameState to play, so it flows like this Title->Transition->Level->Transition->GameOver->Transition->Title…

My game is a Breakout clone, so it doesn’t need to be a fancy system or anything, but I do want to implement something more sophisticated an flexible, but not necessarily more complicated. I don’t like the way the “guts are hanging out” in my implementation, but I just needed to get something working that was easy enough for me to understand straight away.

I’m going to work on implementing it as an interface system like you show, but I still need to grasp the whole StateMachine concept first! I’m not a very advanced programmer, so I’m taking it a step at a time!

I have a question about the method:

interface StateMachine
{
  void setState(state new_state);
  void update();
}

what exact type is the parameter?

Is this a class that implements StateMachine? Or is this a base GameState type?

So would it be something like this?

interface StateMachine
{
  void setState(StateMachine new_state);
  void update();
}

oh, the “state” type is just any class extending a state, so any of the “TitleScreen”, “Level-Menu”, “Loading” etc. GameState.

but then, this is just an idea. if it works better for you having lots of machines or other signatures then just go for it :slight_smile:

@DayTripperID : i like the idea of a more simple construct. what we instantly see is the if-else-chaining in a single method. with only a few states this is totally ok. one advantage of organizing code with a state machine is - pretty much avoiding if-else-chains. this shows once we have many states to deal with.

I totally agree with you about the if else chaining being a nuisance. It doesn’t scale well at all! I have already recoded my system so that any time a class extending GameState is instantiated, you pass another GameState, so for example:

class TitleScreen extends GameState {
   
   private GameState nextGameState;    
   
   public GameState(GameState nextGameState) {
      this.nextGameState = nextGameState;
   }

   public void getNextGameState() {
      return nextGameState;
   }
}

And now, instead of that ugly if else chain, I have this:


public void update() {

   gs.update();

   if (gs.finished) gs = gs.getNextGameState();
}

Syntactically it’s much cleaner, and instead of having many GameStates existing concurrently in the main Game class, I can now instantiate a new one and let the garbage collector take care of the old one. It also means I don’t have to manually reset a GameState. Your insights have really helped me out, I just needed to start with something a little more basic to wrap my brain around! :slight_smile: