Hello again and welcome to another coffee-break tutorial! This series offers quick and easy tutorials that can be implemented in just a few minutes, with the idea being to teach you some basic coding practices using GameMaker Studio 2 that will be useful to you in your own projects. Today's subject is how to pause your games! Note that this tech blog is for Drag and Drop™ users, so if you prefer GML, you should follow the companion tech blog that we've prepared here.
Before continuing, this tutorial uses the finished Space Rocks tutorial project as it's base, so if you're new to GameMaker Studio 2 you should go through that before doing this, although you can download the finished tutorial project from the link below and use that too if you wish:
If you download the above project, you need to open GameMaker Studio 2 and select "Import" on the Start Page to open it, or simply drag it onto the IDE and drop it, which will show you a prompt to import the project.
There are various different ways that you can pause a game, but for this tutorial we're going to use one of the simplest, which is to deactivate all the game instances and then draw a "Pause" screen. Deactivated instances still exist in the game, but they're in a kind of "limbo" where they do nothing - they won't draw and they won't run their events. This makes deactivating things ideal for creating a pause system, although it does create a minor issue... since deactivated instances don't draw, the screen goes blank! However, as you'll see, we can fix that!
To get things started, you need to open up the object
obj_Game. This is the Space Rocks controller object and it's where we will be making the pause system work. To start with, open the Create Event and add in the following variables:
paused will be either
false depending on whether the game is paused or not, and the variable
paused_surf will be used to hold the ID of a surface, which is what we'll use to draw the game to the screen while all the instances are deactivated.
SETTING PAUSED / UNPAUSED
We now need to open up the Step Event of the object
obj_Game. There's already code in this event, so we'll add the pause code after what's there already, beneath the "If Lives" check. The image below illustrates where we want to add the next set of actions:
We'll be using the "P" key to pause the game in this example, but you can use any key really - like escape - or have a button that detects a mouse click or even detect a gamepad button instead.
The DnD™ code to add into this event is:
So, here we're checking to make sure we're in the game room, then we check to see if the "P" key is pressed. If it is pressed, we toggle the
paused variable using the
not operator (
!). We then check if it's
false (the game was paused, but it's just been unpaused) and if it is we activate all the instances in the room and free the surface that we use for drawing while the game is paused. This part is important, as we don't want to keep the surface in memory if it's not required anymore. Note that we also set the
paused_surf variable to -1 again. We do this because we'll be using it as a control for deactivating instances in the Draw Event, which we'll explain in a moment.
The next bit of code in this event is for dealing with the alarms in the controller object. Alarms count down by 1 at the beginning of every step of the game, which means to pause them, we simply add 1 every step while the game is paused! So, we are checking to see if
trueand if it is we add one to each of the alarms.
DRAWING THE PAUSE SCREEN
The final thing we need to do now is in the Draw Event of the
obj_Game object, so open that now. Again, we already have code in this event, so we will need to insert our pause code into the event, in the
rm_Game, at the position marked in the image below:
We'll break the code to add into two sections to make it easier to follow. To start with, we'll have this code:
Here we are checking to see if the
paused variable is
true and if it is we then check to see if the surface we'll be using to draw instead of instances actually exists or not. If it doesn't we then check the
paused_surf variable to see if it's -1 or not, and if it is, we deactivate all the instances except the calling instance which is the game controller (we don't want to deactivate the controller!). Why is this step important? Well, surfaces are volatile which means that things outside the game can destroy them (like minimising the game window), and when that happens the
surface_exists() check will return
false, but the
paused_surf variable won't be -1 (it'll have the ID value of the old surface) and so we won't call the deactivate code again. This means that we will only deactivate objects when the game is paused, and it also means that we can use this section to create other instances after calling the deactivate code - like pause menu buttons or logos or whatever - and they won't be affected by the deactivation.
Next we create our surface and draw the
application_surface to it. The
application_surface is essentially the "canvas" onto which everything in the game is drawn, so by copying it to the paused surface, we are preserving what is currently being drawn to the screen.
The final bit of code to add goes underneath what you've just added at the position shown:
We'll be adding an
else block to the check if the paused surface exists:
Here all that we're doing is drawing the pause surface to the screen, then drawing a low alpha black rectangle over it to make it look "faded", before finally drawing the text "PAUSED" to let the player know that they've paused the game. Really, you code draw anything here, but this is the simplest thing to do and suits this quick tutorial.
You can run the game now, and in the main game room press the "P" key to pause and unpause the game.
That's it for this tutorial! The game has a pause screen, and the code is simple enough that you should be able to add it into your own projects and modify it to suit your needs. Some things you can try that I like to do in my own games are:
lower the game music volume a bit when the game is paused, and return to full volume when unpaused
add in menu buttons to restart the game, go back to the start screen or quit to desktop (for example)
add in some graphic effect when pausing, like gradually dim the surface being drawn, or - if you're feeling brave! - apply a shader to the surface to blur it slightly (I love this effect and use it in my own projects)
Thanks for reading and we hope that this has been interesting and useful to you! If you'd like to see the finished code in the tutorial project without having to actually add it all yourself, or you want to compare what you have with something, you can find download the file below which contains everything we've discussed here.