SPACE SHOOTER

GAMESTATES

WHAT IS A GAMESTATE?

MAIN

The Idea

In your game, we'll need to keep track of different states that the program can exist in. Each state has a different set of rules, behaviors, and controls.

For example, we might have a Title screen that displays an image and allows you to press the space button to start. That's very different from Gameplay which has your players movement controls and has enemies flying across the screen. Finally, Pause might still render the player and enemies, but not move them.

SETTING UP GAMESTATES

MAIN

Tracking the gamestate

To keep track of the current gamestate, we'll simply use a String to give a name to each state. For example, the Title state will be called "title." Make sure you are consistent with your spelling and capitalization throughout your program!

At the top of your program, declare a new global variable:

String gamestate = "gameplay";

Refactoring Update() and Render()

Right now, our program always assumes we're in gameplay mode. We're going to make a new update() method that controls which state we're in. To get started, let's rename the old update and render methods to reflect that they are gameplay specific.

Change the name of update() to updateGameplay()

void updateGameplay()

{

collisions();

...

}


Change the name of render() to renderGameplay()

void updateGameplay()

{

background(0);

...

}


Create a new method called update(). This method is going to determine which gamestate we are in and call the appropriate update method.

void update()

{

if(gamestate.equals("gameplay"))

{

updateGameplay();

}

}


Repeat this process by writing a new render() method:

void render()

{

if(gamestate.equals("gameplay"))

{

renderGameplay();

}

}

Test your program - right now it should run exactly like it did before we changed all this code! Don't worry, it'll pay off soon when we add our first new state.

TITLE

MAIN

Adding The State

You'll need to do a few things to add a new state to our program:

  • Since we want to start on Title, set gamestate equal to "title" at the start of the program.

  • Write methods for updateTitle() and renderTitle(). These can be mostly empty. I recommend printing out a message in text for renderTitle() to test that it works.

  • Modify the core update() and render() methods to check for the Title gamestate and call the appropriate methods.

Test your program - at this point you should see a black screen with your message printing out. Cool, that means we have a working title screen!

Changing States

In the updateTitle() method, add a section of code to detect if the user has pressed a key. If they do so, simply set the gamestate to a new value. For example:

void updateTitle()

{

if(keyPressed)

{

gamestate = "gameplay";

}

}

Test your program - you can now transition from the Title to Gameplay

Making It Look Good

Your Title Screen should have a large background image. You're allowed to use an image from any source (you don't need to make it yourself).

Be sure to include both your Game Name and basic instructions for starting the game, such as "Press Space to Start."

If an element of the title screen doesn't change, you can even just edit the text in photo editor rather than drawing text in Processing.

If you want to get fancy, consider adding animations. Some examples would be: Text that floats onto the screen or making the "press space to start" message blink.

PAUSE

MAIN

Adding The State

You'll need to do all the steps that you did before for Title again to add in the Pause screen.

For the state-specific methods...

    • gameplayPause() can be empty for now

    • renderPause() should just display the word "paused" on the screen

Changing States

In the updateGameplay() method, add a section of code to detect if the user has pressed the 'p' key. If so, change the state to pause.

void updateGameplay()

{

if(getKey('p'))

{

gamestate = "pause";

}

}

Test your program - you can now transition from the Gameplay to Pause

Improving Your Pause Screen

Right now when you pause it hides the whole screen, which is quite jarring to the user. Let's add one line of code to your renderPause() method:

void renderPause()

{

renderGameplay();
...

}


By calling the renderGameplay() method, we simply display everything we normally would draw. Yet we aren't calling updateGameplay() - so nothing moves!

Make sure you still have a pause message displaying afterward.

Test your program - you can now transition from the Title to Gameplay

There And Back Again

In updatePause(), add code to return back to the game:

void updatePause()

{

if(getKey('p'))

{

gamestate = "gameplay";

}

}

Test your program - notice that something is WEIRD. You're actually pausing and unpausing repeatedly. Sometimes it might even leave you back on Gameplay. This is because the state is switching every frame as long as the 'p' key is held down. We need one last step...

Toggles and Timers

We'll need to add a timer to track how long it has been since the user pressed the 'p' key and only register the keyPress every so often (let's say every 15 frames).

Start by declaring a new global variable at the top of your program:

int pauseTimer = 0;


Each frame we'll decrease this value by 1 as long as it's greater than zero. Since this is just a timer, and it is used in multiple states, modify it in the update method().

void update()

{

if(pauseTimer > 0)

{

pauseTimer--;

}

...

}


Next, we'll modify the code that switches from pause to gameplay to both check for the timer and assign it a new value.


void updatePause()

{

if(getKey('p') && pauseTimer == 0)

{

gamestate = "gameplay";

pauseTimer = 15;

}

}


We're almost there. If you run the program right now, you'll likely get stuck back on pause. We'll need to add the pauseTimer code into the version found in updateGameplay too!

void updateGameplay()

{

if(getKey('p') && pauseTimer == 0)

{

gamestate = "pause";

pauseTimer = 15;

}

}


Test your program - now it should work reasonably. Feel free to adjust the time for a key press.