Making Fire Jump | Part 3


Making Fire Jump | Part 3

Welcome to the Fire Jump tutorial! This series will take you through developing an infinite platformer game in GameMaker using GML Visual. You will learn how to make a playable character, generate infinite obstacles, build a solid game loop along with menus and much more.

undefined

This is Part 3 of a 4-part series, all of which are available for free on this site. You can refer to the index page to navigate to the other parts.

Here is a video version of this tutorial:

Overview

In the previous part, we added civilians that could be rescued, and scores to show how many civilians you had rescued and how high you had climbed. Now we’re going to add fire to some windows which defeats the player, and foam that the player can shoot to put out those fires. We’ll also add sound effects to make the game experience more enjoyable.

This page is divided into the following sections:

  1. Spawning Fire Obstacles
  2. Losing From Fire
  3. Losing From Falling Down
  4. Shooting Foam
  5. Fire Out Particles
  6. Sound Effects

We will make use of a variety of image assets for our in-game elements and interface animations, which you can download by clicking here.

Spawning Fire Obstacles

Fires will be spawned on random windows, just like civilians, and will hurt the player when they collide.

Fire Sprite

We need to import a sprite for our fire. In your Asset Browser, find the “Sprites” group and create a new Sprite asset. We’ll call this “spr_fire”. In the tutorial's art assets, you will find a file called spr_fire_strip17 in the "Animations" folder, which you can import through the Sprite Editor. The file has _strip17 at the end of its name as it is a 17-frame animation.

undefined

Set the origin for this sprite to “Bottom Centre” so we can place it nicely on a window, just like we did with the civilian. We also need to adjust its mask, so expand the “Collision Mask” menu in the Sprite Editor, change the “Mode” to “Manual” and adjust the rectangle to look something like this:

undefined

This mask ensures that the player cannot lose by touching the top part of the sprite, which doesn’t actually contain any fire. You can also make this mask narrower to make the game easier, or make it wider to increase the challenge!

Fire Object

Let’s create an object for our fire. Go to the “Objects” group in your Asset Browser, and create a new Object asset called “obj_fire”. Assign the fire sprite to this object. Open its “Parent” menu and assign the obj_move_parent as its parent, so it moves down along with the windows.

undefined

Let’s add a Step event to this object. We want this event to destroy the instance if it goes below the room, so we first need a condition. In the Toolbox, find the “If Variable” action and drop it into the event. Set the “Variable” field to y, the “Is” field to “Greater” and the “Value” field to room_height + 200.

Now find the “Destroy Instance” action in the Toolbox, and attach it to the right of the “If Variable” action. The instance will now be destroyed when it goes lower than 30 pixels below the room.

undefined

Spawning Fire

We’re spawning our civilians in the window object, so we’ll do the same for fires. In your Asset Browser, find obj_window and open its Step event.

Let's look at this part of the event:

undefined

We have a “Get Random Number” action in this event, which gets a random integer in the 0-1 range. If that number is 0, it spawns a civilian, and if it’s 1 it spawns nothing. We can spawn a fire when the number is 1, however that would leave no empty windows since these are the only two possible numbers.

In the “Get Random Number” action, change the “Maximum” field to 3. Now there are four possible numbers: 0, 1, 2 and 3, and if we spawn a fire when the number is 1, there will still be two cases left for empty windows.

In the Toolbox, search for the “Case” action and drop it into the Switch action. Set the “Constant” for this case to 1, so it runs when the chance variable is equal to 1.

Let’s spawn the fire now. In the Toolbox, search for the “Create Instance” action and attach it to your new Case action. Set the “Object” field to obj_fire (or find it through the Asset Explorer button). We want to create the fire directly on the window, so enable the “Relative” checkboxes for both “X” and “Y” fields (leave their values at 0). For the “Layer” field, enter “Spawns” (with quotes, as this is a string).

undefined

That creates the fire instance, but we also need to open the window and assign the correct frame. The window sprite has three frames (0, 1 and 2) where 0 is closed, 1 is open for a civilian, and 2 is open for a fire.

undefined

Let’s add another action to this case. In the Toolbox, search for “Set Sprite” and drop it under the “Case” action. Set the “Sprite” field to spr_window (or find it through the Asset Explorer) and the “Frame” field to 2, as that is the frame we want to switch to.

undefined

If you run the game now, you will see fires spawn on random windows, and they automatically move down because we assigned the correct parent:

undefined

Losing From Fire

We’re now spawning fires, but they don’t affect the player. We’ll make it so that the player loses immediately on touching a fire.

Defeated Player

We’ll create a separate object for the defeated player, and for that we need to import a sprite first. In your Asset Browser, go into the “Sprites” group and create a new Sprite asset, with the name “spr_player_defeated”. You can find the image in the tutorial’s assets folder with the same name, and once you have imported it, make sure to set the origin to “Middle Centre”.

undefined

Let’s create an object now. In your “Objects” group, create a new Object asset and name it “obj_player_defeated”. Assign the spr_player_defeated sprite to it.

We want this object to jump up and fall down, similar to how the civilian does when it is rescued. In the Events window for this object, click on “Add Event” and select “Create”. We’ll give the defeated player a vertical speed and gravity force in this event.

In the Toolbox, search for “Set Speed” and drop it into the event. Set the “Type” field to “Vertical” and the “Speed” field to -25 (you can change this if you want to make it jump higher or lower). Then, search for the “Set Gravity Force” action, drop it into the event and set its “Force” field to 1.

undefined

This will make the defeated player instance jump up and fall down. When it does fall far enough to go below the room, we want to restart our game to give the player another chance.

Add the Step event into this object. In the Toolbox, search for “If Variable” and drop that action into the event. We want to check if the player has fallen below the room, with a margin of 50 pixels. Set the “Variable” field to y, the “Is” field to “Greater” and the “Value” field to room_height + 50.

To restart the game once this happens, search for the “Restart Game” action and attach it to the “If Variable” action.

undefined

We can now create an instance of this defeated player object, which will automatically restart the game once it falls below the room. The perfect place to do that would be a collision event between the player and fire objects!

Fire Collision

Open obj_player and add a new Collision event with the obj_fire object. Here, we are going to do two things:

  1. Create an instance of obj_player_defeated
  2. Delete the player instance

This way the player will effectively “transition” from its normal state to being defeated.

In the Toolbox, search for the “Create Instance” action and drop it into the event. Set the “Object” field to obj_player_defeated (or use the Asset Explorer button to find it).

We want to create the new instance exactly where the player is, so enable the “Relative” checkboxes for the “X” and “Y” fields while leaving their values at 0. Finally, set the “Layer” field to “Player” as that is where the player exists.

Now to destroy the player itself, search for the “Destroy Instance” action and drop it into the event. This will destroy the instance that is running the action, which is obj_player.

undefined

Run the game and you will see that the player loses on touching a fire. When it falls below the room, the game restarts and you get to play again:

undefined

We have a solid game loop now that we can build on to further improve our game!

Losing From Falling Down

Our game allows the player to jump as high as they can, which means that they can also fail to land on a window and fall all the way down. The problem is that nothing happens if the player falls down, and the game is essentially stuck -- so we need to restart the game if the player falls down on its own.

We’re going to do this in a new event, however we don’t have to start from scratch. We just added a collision event with the fire object to defeat the player, so we’ll use the same actions we added there in our new event.

We can duplicate an event which allows us to select a new event type, and carries over the actions from that event into the new one. Go into obj_player and open the Events window. Find the collision event with obj_fire, right click on it and select "Duplicate Event".

undefined

This will open the events list. Go into “Other” and select the “Intersect Boundary” event. This event runs when the player intersects with (or touches) the boundary of the room.

undefined

The event will be added to the object, and you will see that it already has some actions: these are from the event we copied.

This event will now create an instance of the defeated player object and destroy the player itself, whenever the player touches any boundary of the room. This is not convenient, as you will find that the player loses on touching the left and right edges as well:

undefined

We only want this to defeat the player if it touches the bottom edge of the room. To fix this we can use a condition, so in the Toolbox, search for “If Variable” and drop it into the event.

Set the “Variable” field to y, the “Is” field to “Greater or Equal” (so the Y can be greater than the value or equal to it) and the “Value” field to room_height. This will now check if the player’s Y position is at or below the bottom edge of the room, and since this is the condition we wanted, drag the existing actions in the room and attach them to the “If Variable” action.

undefined

If you run the game now, you will see that the player only loses on touching the bottom boundary of the room!

undefined

Shooting Foam

You can already feel that the fire is annoying -- no one likes to lose! That is why we are going to give the player the ability to put out fires by shooting foam upwards. This presents a challenge to the player as they can only put out a fire if they are below it.

undefined

Foam Sprite & Object

Let’s import a sprite first. Go into the “Sprites” group in your Asset Browser, and create a new Sprite asset called “spr_foam”. In the tutorial's art assets, you will find a file called spr_foam_strip20 in the "Animations" folder to import, and it has a _strip20 suffix as this is a 20-frame animation. After importing the animation, set the origin to “Middle Centre”.

undefined

What we need now is, of course, an object for this. Go into the “Objects” group, and create a new object called “obj_foam”. Assign the spr_foam sprite to it, then open the Parent menu and assign obj_move_parent as its parent object.

undefined

The player will be shooting this foam upward, so we want it to move up. Add the Create event to this object, and from its Toolbox, find the “Set Speed” action. Add it to the event and set the Vertical speed to -40:

undefined

This ensures that the foam always moves up after it’s created. You can also change the speed from -40 to anything else if you want to make the foam go faster or slower.

We want this foam to be destroyed when it goes out of the room, and luckily we don’t have to use a condition for this. Previously whenever we used a “check if Y is below the room” condition, we did that so the instance wouldn’t get destroyed when it was created above the room (like the windows, fires, and civilians). However, the foam is created within the room, which is why we don’t need to worry about that this time.

In the Events window, click on “Add Event”, go under “Other” and select “Outside Room”. This event runs whenever the instance goes out of the room. In the Toolbox, search for “Destroy Instance” and drop it in the room.

undefined

Foam instances will now be destroyed whenever they go out of the room!

Space Key

We’ll use the Space key to shoot the foam. Open obj_player, go to its Events window, click on “Add Event” and under “Key Pressed”, select the “Space” event.

undefined

This event will run when the Space key is pressed on the keyboard. Since this is a “Key Pressed” event and not a “Key Down” event, it’ll only run once when the key is hit, and holding the key will not do anything.

We want to create a foam instance when this key is pressed, so in the Toolbox, search for the “Create Instance” action and drop it into the event.

Set the “Object” field to obj_foam (or find it through the Asset Explorer), and to create the foam where the player is, enable “Relative” for the “X” and “Y” fields while leaving their values at 0. Finally, set the “Layer” field to “Spawns” (the same layer that we used for spawning civilians and fires).

undefined

This will now create a foam instance when the Space key is pressed. Let’s fill in the final piece of the puzzle and program what happens when the foam and fire collide!

Putting Out Fires

We will do this in the fire object, so open obj_fire from your Asset Browser. In its Events window, click on “Add Event” and add a Collision event with obj_foam.

When a collision occurs between a fire and a foam, we want both of them to be destroyed. First, to destroy the fire (which is the current instance), search for the “Destroy Instance” action and drop it into the event. This will destroy the fire instance, so let’s now see how we can destroy the foam instance as well.

This is a collision event between the fire and the foam, where the event itself is in the fire object. So within the collision event, the fire is known as “self” as that’s the instance where the event is running. Hence the other instance in the collision, the foam, is known as “other”.

We want to add a new “Destroy Instance” action and apply it to that “other” instance. From the Toolbox, add another “Destroy Instance” action into the event. Click on the little arrow next to the close (X) button, and select “Other”. This action will now apply to the foam instance, which will be destroyed!

undefined

We can now shoot foam and destroy fire!

undefined

Fire Out Particles

Right now, hitting a fire with foam makes it disappear instantly. We want there to be an animation of the fire going out, however instead of using sprite animations, we’re going to make use of GameMaker’s particle system:

undefined

Particle Sprite

Let’s import the particle image first. Create a new Sprite called “spr_fire_particle”, and import an image for it from the tutorial’s "Animations" folder (there will be a strip image called spr_fire_particle_strip17). Set the origin to “Bottom Centre”.

undefined

Effects Layer

We’re going to create a new layer in our room. Open rm_game, and in the Layers panel, create a new Instance layer. Name it “Effects”, and make sure to place it at the top (even above the HUD layer) so that any effects we create are always visible.

undefined

Defining Particles

We need to create the particles now, which we’ll do in a new object. Go to the “Objects” group in your Asset Browser and create a new object called “obj_game”. This object will not be visual, so you don’t need to assign a sprite to it. It will simply run in the background and manage our particle system.

Go into the rm_game room and drop an instance of this object into the Effects layer. You will see a question mark on the instance, which is expected as the object doesn’t have a sprite.

undefined

Now we'll open the obj_game object and add the Create event. In this event we will create:

  1. A Particle System, which manages particles
  2. A Particle Type, which is the actual particle that is created (in our case, fire)

Let’s create a Particle System first. In the Toolbox, search for “Create Particle System” and drop it into the event. Let’s look at its fields:

  1. “Layer” is the room layer where this system will create particles. Set this to “Effects” (with quotes).
  2. “Persistent” controls whether this Particle System is for the current room only (disabled) or for all rooms (enabled). Leave this disabled as we only want it for this room.
  3. “Target” is the variable that will store this Particle System. Set this to particle_system and make sure that “Temp” is disabled (we don’t want this variable to be temporary).

undefined

Now let’s create a Particle Type for our fire. In the Toolbox, search for “Create Particle Type” and drop it into the event. This action simply creates an empty Particle Type, without defining what it looks like, which we can do later using other actions. Let’s look at its fields:

  • “Target” is the name of the variable that will store this Particle Type. Set this to fire and make sure that “Temp” is disabled.
  • “Blend” controls whether this particle appears normally or uses additive blending. Additive blending should be used if your particles give off light, and since fires do give off light, we’re going to enable this. This will make the fire particles appear brighter and warmer.

undefined

We'll now define the properties of this particle type, to control what it looks like and how it moves. Each property is set using a new action, so we’re going to add some actions to define this particle type. Note that each action that we’ll add has a “Type” field which is the Particle Type that we are editing, so set that field to fire for all subsequent actions.

Let's add the following actions:

Note: The order of these actions does not need to be the same as the order given below. Also, feel free to change any values for the particle type and experiment with them!

  1. “Set Particle Sprite”

    This sets the sprite that the particle uses. Set “Type” to fire and the “Sprite” to spr_fire_particle.

  2. “Set Particle Life”

    This sets the life range of the particle. The life of a particle is how many frames it lasts for, and it is randomly selected between the “Min” and “Max” range.

    Set “Type” to fire, “Min Life” to 10 and “Max Life” to 15.

  3. “Set Particle Speed”

    This sets the speed of the particle, and just like the "life" property, it has a minimum value and a maximum value so that a random speed is selected within this range. The “Increase” value is how much the speed increases (or decreases) per frame. The “Wiggle” value is similar but the increase is randomly selected within its range, so the particle wiggles as it moves.

    Set “Type” to fire, “Min Speed” to 2, “Max Speed” to 4, “Increase” to -0.01 and “Wiggle” to 0 (we’re giving it a negative "Increase" value so it slows down over time).

  4. “Set Particle Direction”

    This controls the direction in which the particle moves. It also has a range, an increase value and a wiggle value. We’ll set the direction range to 0-360 so that it can get any random direction, and give it a positive increase so its direction slowly changes (to give it more life).

    Set “Type” to fire, “Min Dir” to 0, “Max Dir” to 360, “Increase” to 1 and “Wiggle” to 0.

  5. “Set Particle Size”

    This controls the size of the particle. It allows a range for the size to be random, and also allows you to increase or decrease the size every step.

    Set “Type” to fire, “Min Size” to 0.7, “Max Size” to 1.2, “Increase” to 0.04 and “Wiggle” to 0. This way fire particles can be between 0.7x and 1.2x scale and will increase in size by 0.04 every step.

  6. Finally, “Set Particle Alpha”

    This lets us specify an animated alpha/transparency for the particle. 1 is fully visible and 0 is invisible. We’ll make it go from 1 to 0 so that the particle fades away as it moves.

    Set “Type” to fire.
    “Start” is the particle's alpha when it is created. Set this to 1.
    “Middle” is the alpha at the middle of the particle’s life. Set this to 0.8.
    “End” is the alpha at the end of the particle’s life. Set this to 0.

    This way our particle will be at full opacity in the beginning, at 80% opacity in the middle of its lifespan and 0% by the end - giving us a nice fade effect!

Here are the new actions we've just added:

undefined

Feel free to change up any of these values to personalize the look of your particles!

Cleaning Up

We should delete our Particle System and Type when they’re no longer needed, otherwise it will cause memory leaks as they’re created in each round but never deleted.

For this we will add the “Clean Up” event to the object. This event runs when the instance stops existing (when it’s deleted or the room ends) so we can use it to destroy our particle resources.

undefined

Once the event has been added, search for the “Destroy Particle Type” action and drop it into the event. This does exactly what it says (which is destroying a Particle Type) so set the “Type” field to fire so that our Fire Particle Type is destroyed when the room ends.

Now search for the “Destroy Particle System” action and drop it into the event. Set the “System” field to particle_system so that our Particle System is also destroyed when the room ends.

undefined

This will now destroy the particle resources that we created in the Create event. There will be no memory leaks now!

Spawning Particles

We’ve defined our particles now, so we need to spawn them when a fire goes out. Go into the obj_fire object, and open its Collision event with obj_foam.

In the Toolbox, search for “Burst Particles” and drop it into the event. This action spawns particles in the given system, using the given type. Our Particle System and Type variables exist in the obj_game object, so we'll need to pull those variables from that object so we can use them. This is done by writing the object’s name before the variable, like so:

object.variable

Usually, using the object's name before the dot (".") can cause problems as there can be multiple instances of an object in a room and you wouldn't know which instance it would target. However, since we are sure that we only have one obj_game instance in our room, we should be okay to use the object's name here.

Set the “System” field to obj_game.particle_system, and the “Type” field to obj_game.fire. This will successfully pull those variables from obj_game and pass them into this action.

The “X” and “Y” fields control where the particles are created. We want them to be created exactly where the fire instance is, so enable “Relative” for both of them while leaving their values at 0.

The “Count” is the number of particles that are created. Let’s set this to 4, but feel free to change this to whatever you like.

undefined

Extinguishing a fire will now spawn those particles, and give a smooth transition to the fire going out!

undefined

Sound Effects

Our game currently plays really well, however it doesn’t feel complete because it has no sounds! Let’s add sound effects and music to our game now.

Sound Assets

We’re going to add sound assets to our game, just like we added sprites and objects. Select the “Sounds” group in your Asset Browser, or create one if you don’t have it. Open the Create Asset menu at the top and create a new Sound asset. We’ll name this “snd_game_music”.

Note: The “snd_” prefix refers to this being a sound asset.

undefined

This will be the background music for our game. In your workspace, you will see the Sound Editor open for this sound. Click the [...] button next to the “Name” field, which opens the File Explorer to let you import a sound file. This tutorial’s assets folder includes an "Audio" folder, where you can find “snd_game_music.mp3” and import it.

undefined

In the Sound Editor window you can play the sound and adjust its volume. We don't need to worry about the other settings for now, however if you're curious you can read about them on this manual page.

Now add another sound asset in the “Sounds” group, and call this snd_player_jump. This is a sound effect that plays when the player jumps. You need to import “snd_player_jump.wav” from the tutorial’s audio assets.

In the same manner, create the following sound assets and import them from the audio assets folder:

  • snd_player_defeat - Plays when the player is defeated by a fire
  • snd_civilian_rescue - Plays when a civilian is rescued
  • snd_player_shoot - Plays when the player shoots out foam
  • snd_fire_out - Plays when a fire is extinguished

All the sound assets we need have been imported, so now let’s play them!

Game Music

We need to play the music as soon as the game begins, so we’ll do that in the obj_game object. Find that object and open it, then go into its Create event.

First of all, we’re going to add an action called “Stop All Audio”, so find it in the Toolbox and drop it in the event. This is going to stop all the game audio that is playing at that moment. Right now there is no audio for this action to stop, however when we add a main menu, the audio played by the menu will be stopped by this action.

With all the previous audio stopped, we can now play the game music. In the Toolbox, search for the “Play Audio” action and drop it below “Stop All Audio” (if you place it above that action, the game music will also be stopped).

Set the “Sound” field to snd_game_music (or find it through the Asset Explorer button on the right). “Loop” controls whether the sound repeats after it ends, and since the music should never stop, we need to enable this. Leave the rest at default.

undefined

Player Sounds

We’re going to play the player-related sounds now.

Go to obj_player, and open its Collision event with obj_window. Here we’re going to play the jump sound as this event causes the player to jump. In the Toolbox, search for “Play Audio” and drop it into the action chain, so it’s controlled by the condition at the top.

Set the “Sound” field to snd_player_jump (or find it through the Asset Explorer). “Loop” should be disabled as we don’t want the sound effect to keep repeating, instead it should play once and stop.

undefined

Now we’ll play a sound when the player shoots foam. Open the “Key Press - Space” event, and add a “Play Audio” action. Use this action to play the snd_player_shoot sound without looping.

undefined

We also need to play a sound when the player is defeated, so we’ll go into the obj_player_defeated object. Open its Create event, and add a “Play Audio” action. Use this action to play the snd_player_defeat sound.

When the player is defeated, we will stop the game music to indicate that the game really has ended. To achieve this, find the “Stop Audio” action, drop it in the event and set the “Sound” field to snd_game_music (as that is the sound that we want to stop).

undefined

This will now play the player defeat sound, and at the same time, stop the game music.

Civilian Rescue

To play a sound when a civilian is rescued, go into obj_civilian and open its Collision event with obj_player. Here we have a condition to check whether rescued is equal to false, so our new audio action should be attached to this condition.

Find the “Play Audio” action in the Toolbox, and attach it to the “If Variable” action. Set the “Sound” field to snd_civilian_rescue.

Fire Going Out

For the fire going out sound, go into obj_fire and open its Collision event with obj_foam. Here, simply drop a “Play Audio” action (it does not need to be in any conditions) and set the “Sound” field to snd_fire_out.

We have now implemented all of the sounds that we imported, so run the game and see how your game now offers a much better experience with proper audio feedback. You can also import more sound assets and play them using the “Play Audio” action!

Summary

Before we add more functionality to our game, let’s summarize what we have learned in this part:

  1. Collision events have a “self” instance and an “other” instance, actions can be applied to other
  2. The look of a particle can be defined by creating a Particle Type
  3. Dynamic resources such as Particle Systems and Particle Types must be destroyed in the Clean Up event
  4. Sounds can be played using the “Play Audio” action
  5. Finally: Good job on finishing this part!

Let’s finish up our game by adding a main menu and a game over screen, and also offer the player a more rewarding experience by adding a highscore feature.

Next: Fire Jump Tutorial - Part 4