Creating hazards
So our player can move and shoot. That's great, but what fun is that when there are no obstacles? Hazards offer a great challenge and can even be the core of your gameplay. How boring would Mario Kart be without banana peels? Or Pitfall without…well, the pits? Video game hazards come in many forms and, if you play games, you've likely encountered most, if not all of them. Spikes, lasers, electrical traps, and falling objects are a few examples, but they have at least one thing in common: if your player character touches them, he/she will be hurt or killed. Now, in most games the latter isn't permanent, what with health bars and lives (we'll get into those later), but it remains a major part of the gameplay. Let's look at creating some simple hazards that can give your players a hard time.
Getting ready
In-game hazards can come in many forms and various visual styles. Like the projectiles we discussed previously they can be static images, but they look much better as animated sprites. We're going to build a spike trap; you can use your own art, but I've included an animated sprite in the downloadable files.
- Create a sprite, name it
spr_hazard_spike
, and load the necessary images. Before we move, on you're going to need to set up the sprite's collision mask. Sprites are assigned a collision mask by default but you can modify it to your own needs. We only want the trap to be activated and for the player to take damage when the spikes are actually touched, as opposed to the area around the trap. - Under Collision Checking make sure Precise collision checking is selected.
- Click Modify Mask and, under Shape, select Precise. To the left of that is a slider that allows you to specify Alpha Tolerance. This is useful because it allows you to shrink and grow the mask according to the sprite's outline (the empty space around it being an alpha map).
Once you save your selections we're ready to get started.
How to do it...
- Begin by creating a new object called
obj_hazard_spike
and assigning the sprite you made previously. - Add a Create event and drag and drop two instances of Set Variable. One will set
image_speed
to0
, the other will settrap_set
to1
. - Add a Collision event with
obj_player
as the target. - Drag and drop Test Variable to the Actions box, checking that
trap_set
is equal to1
. - Place both a Start and End Block in the Actions box. Within this block you'll need two Set Variables; one that sets
trap_set
to0
, and another that setsimage_speed
to1
. - Still within the block, set
Alarm 0
to60
. Your Actions box should now look like this:Tip
Downloading the example code
You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
- Create the event for
Alarm 0
. - In the Actions box, drag and drop Set Variable, setting
image_speed
to1
. - Drag and drop Set Alarm, setting
Alarm 1
to30
. - Add the event for
Alarm 1
, where you'll dragSet Variable
and have it settrap_set
to1
. - Add a Step Event and drag Test Variable to the Actions box and have it test whether or not
image_index
is equal to4
. - This should be followed by a Start and End Block. Within this block should be a Test Variable that checks whether or not
alarm[0]
is greater than0
, as well as another Start and End Block. - Within this block you'll need a Set Variable that sets
image_speed
to0
. When you're done, the Actions box should look like this: - Finally, click Add Event, then Other, and select Animation End.
- All you need in the Actions box here is a Set Variable that sets
image_speed
to0
.
Got all that? It's a lot to do all at once, but we'll go through what it does, step by step. The good news is that you now have a spike trap that springs when touched by the player and stays sprung for a bit before retracting. There's a good reason behind this that we'll explore a little further once we get into player health.
How it works...
The trap you've just made uses collision detection and alarms to set and reset variables that control the trap's state. On creation, GameMaker sets the image_speed
to 0
, keeping the animation on the 1st frame, and establishes the variable trap_set
, which will only be used by this particular instance of the spike trap. Think of trap_set
as a sort of on/off switch, using binary (0
or 1
) to dictate its current state. When the player collides with the trap, GameMaker checks whether or not the trap is on. If trap_set
is equal to 1
(on), GameMaker proceeds to set image_speed
to 1
(so the animation will begin to play), set Alarm 0
to 60 steps, and reset trap_set
to 0
so that the spike trap will not be activated over and over again. This is to give the player a chance to move away from the trap to avoid being injured a second time. The Step Event checks every single step to see whether or not the sprite's animation has advanced to frame number 4
. If it has, it then checks whether or not Alarm 0
is still counting down. If it is, image_speed
is set to 0
, so that the animation remains on the 4th frame (in the up position) until Alarm 0
is finished counting down. When it has, the image_speed
is set back to 1
, allowing the animation to continue, and Alarm 1
is set to 30 steps. The animation can continue (retracting the spikes) but once it reaches the last frame, the Animation End event then sets image_speed
to 0
again, preventing the animation from looping. The last thing to happen in this long list of events is the end of Alarm 1
, which simply gives trap_set
a value of 1
, thereby resetting the trap to be used again.
It's a lot to take in at once, but creating this trap is a great demonstration of the programming logic we're going to get into later on. For now, enjoy your new spike trap!