GameMaker Tutorials: Pausing the Game

 
One of the features I see many people struggle with when creating their games is the ability to pause the game. Part of the reason for this is that it is usually something they try to tack on late in development, which usually means adding a lot of conditional code to most scripts. This becomes very tedious and ends up adding in a bunch of bugs. In this tutorial, we will create a simple system that can help make pausing the game much easier.


Download the Work File (.gmz)

Pausing with the Game Object

The ability to pause a game should be one of the first systems created as everything in the game will be affected by it. This means thinking about every type of asset you plan using, how it can be paused and more importantly, how it can be unpaused correctly. The example game we are going to build is deceivingly simple. We will have a ship with Animation that follows a Path around the screen, firing two different missiles on a Timeline with a Sound effect on launch. One missile will move by adjusting the X coordinate in the Step event and have a Particle effect. The other missile will use hspeed to move and will have an Alarm to play a sound effect. As you can see, that is a lot of different things we need to keep track of.

The first thing we should create is an object, obj_GameObject,  that all other objects we want paused in the game are parented to. We need to initialize some variables that we will want to use in the Create event.

Here we have variables for the speed, direction, animation, and path speed all set to 0 for a default. We need a couple of boolean variables for timelines and sound to ensure that they are only activated if they were running already. We will be using these variables in the scripts we will need to pausing the game and unpausing. We will start by pausing everything with a script called scr_GamePause.

Here we are pausing everything in the game, but let’s take a closer look at what we are doing and understand what is going to be affected. We start with the movement by grabbing the current speed and direction of the instance and then setting the speed to zero. We also do the same for animation. Sound is a bit more tricky as not every object will have audio and we don’t want it to error out. Therefore we use the hasSound variable, which will need to be set to true in every object that has a sound, for this to work cleanly. Next up, we run a for loop grabbing the current time remaining on every alarm and putting it into an array and then set the alarm to -1 which turns it off. Moving onto timelines, we check to see if there is timeline is currently running, and if so turn it off. For paths we check to see if it is active and if it is, we grab the current speed and stop it. Finally, because we will have particles, we can just turn off the particle updating system all together. Please note that here we are using a single, global particle system. Now that we can pause the game, let’s unpause it with a new script, scr_GameUnpause.

This is pretty much the opposite of what we just did, in that we pass all the variables back into the appropriate places. Next we need to put this into the obj_GameObject. For this we will use two User Defined Events, specifically User Event 14 (scr_GamePause) and 15 (scr_GameUnpause). Why those two? Because most games don’t need 14 other user-defined events and we are unlikely ever to use them otherwise, which means they are safe to use. To make our code a bit more readable let’s define two Constants, PAUSE = 14 and UNPAUSE = 15.

The Ship and Missiles

Now that we have the parent object, we can build the ship and missiles. We will start with the obj_Ship, which will need a Path, pth_Square, to have it move around the screen, a Sound, snd_Fire, for when it shoots a missile, and a Timeline, tm_Shoot, for when the ship should shoot. We only need a single script in the Create event to activate everything.

The first and most important thing we need to do here is use the event_inherited function which will run the obj_GameObject’s Create event so we initialize all the variables. This will need to be done for every pausable object in the game that has a Create event. We then initialize the sound we will need, the timeline and the path. This ship is now ready to go!

Next we will create the first missile, obj_Rocket, which will move across the screen by changing its X coordinate and will have Particles spraying behind it. We will start with the Create event script that will initialize the particles. Please note that the particle system is not created here as it will be a global variable we will create later.

We created a particle and an emitter and are now ready for the Step event. Since this event runs every step of the game, we will need a global variable, global.isPaused, to indicate when the gameplay should be run. We start by checking if the game is not currently paused. If it isn’t, we move the object and fire a burst of particles.

Now for the final missile, obj_Bullet, which will use hspeed to move across the screen and will have an alarm that will play a sound every second. Let’s initialize everything!

We will want the alarm to play a sound and then repeat it self manually so that we know that the alarm has paused. Once that is done all our pausable game objects will be complete!

Don’t Forget the Overlord

Not every object in the game should be able to be paused. We need at least one object that sits outside of this system so that we can unpause things! In this case we will use obj_Overlord to control everything. We have some global variables we want to initialize and for the sake of simplicity, we will put into the Create event. (Normally I wouldn’t do this)

With the global variables all set, we can now build the script to pause the game, scr_PauseTheGame. This script can be applied in many different ways, but for this project we will attach it to the Overlord’s Key Press event with the P key.

Here we use a simple switch statement to pause and unpause the game. If the game is to be paused, we run the User Defined Event 14 (event_user(PAUSE)) on all obj_GameObject. If we are unpausing, we run the other user event. We now have a game that can be paused properly, but we aren’t done yet! Everything stops, but we don’t have any feedback letting the user know that the game is paused. Let’s fix that by adding a DrawGUI event to the Overlord that only displays some text when the game is paused.

One final touch, which is actually very important when creating for mobile games, is we should pause the game automatically if the focus is lost, such as the user clicks onto another app. This is very easily done by using the os_is_paused function that does this exact check in a Step event in the Overlord.

That’s it! We have been able to properly pause all movement, audio, alarms, timelines, particles and paths. We have kept things simple by using a global variable and parent object to control all of this. A fully functioning pause system that can be applied to almost any game.

Download the Completed File (.gmz)

If you liked this tutorial and are thinking “Golly, if only there were a book on all this.” Then your wish has come true! 
Check out my book here! If you want to see what you will learn, I have playable versions of the projects here!
HTML5 Game Development with GameMaker

4 thoughts on “GameMaker Tutorials: Pausing the Game

  1. Hi Jason, I have your book, and it help a lot!
    Maybe you can make a second part of the book, with this tutorials?
    For example the pause system, polishing the game, in app purchases, menus, credit, settings, etc.
    In this tutorial at the end you call scr_PauseTheGame(); But at the begging of the tutorial you created: scr_GamePause();
    So scr_PauseTheGame(); is the same as scr_GamePause();?
    Thanks, Simon!

  2. No, scr_PauseTheGame() is the script you are building for the Overlord that will then cause all the objects to pause. scr_GamePause is the script that pauses all the alarms, timelines, etc.

  3. Hey Jason, you said that you wouldn’t initialize the variables on the Overlord Create, then where would you and why? What’s the difference?

  4. I usually create a Globals object and place it in the splash screen. I believe all globals should be initialized before anything meaning happens!

Leave a Reply