Fire Jump | DnD | Part 2


Fire Jump | DnD | Part 2

Welcome to the Fire Jump tutorial! This series will take you through developing an infinite platformer game in GameMaker Studio 2 using Drag and Drop™. 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 2 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.

Overview

In the previous part, we created a basic example with a jumping player and infinitely spawning windows. Now we will expand on that example to add player animations, civilians to rescue and scores.

This page is divided into the following sections:

  1. Player States
  2. Spawning Civilians
  3. Rescuing Civilians
  4. Rescue Score
  5. Height Score
  6. Bonus: Jump Effect

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.

Player States

Importing Sprites

We’ve made the player move exactly as we wanted, however it appears to be stuck in the same animation. That’s because we only imported one sprite for the player and that is all we see.

We’re going to import two more sprites to animate our player. Go into your Asset Browser, and in the “Sprites” group, create two new sprite assets: "spr_player_jump" and "spr_player_fall". You can find both of these sprites in this tutorial’s art assets folder, which you can import and use.

undefined

Make sure to set the origins for these sprites to “Middle-Center”.

Let’s open the spr_player_jump sprite and make a small adjustment. We want this state to have a time limit, so it should only run for a few frames and then switch to another state. For that we are going to use its “sub-images” (or frames) feature, although you will notice that this sprite only has one frame.

We can extend a sub-image so that it lasts for multiple frames instead of only one. Place your mouse cursor near the right edge of the first frame, and drag it out so it lasts for about 8 frames. This sprite will now function as an 8-frame animation that we can run when we want!

undefined

Now we have three player sprites in total, for the three states that it’s going to be in:

  • spr_player_jump: The jump state which plays after you bounce off a window
  • spr_player_air: The “in-air” state that plays after the jump state is over
  • spr_player_fall: The fall state that plays as the player is falling down

We can easily change the sprite of an object using actions, so let’s program our player to display the correct sprite depending on its state.

Jump State

We want the jump state to play when the player bounces off a window. To implement this, let’s go into obj_player and open its Collision Event with obj_window.

This event currently checks if the player is falling, and sets its vertical speed so that it jumps again. We also want to change its sprite at the same moment, so go into the Toolbox and search for the “Set Sprite” action. When you have found it, drag and drop the action to the right of the “If Variable” action, so that it’s controlled by that condition.

This action changes the sprite of the instance to the one set in the “Sprite” field. You can click on the undefined icon next to that field to open the Asset Explorer, which will allow you to select a sprite asset. At this point we want the player to switch over to spr_player_jump, so find that sprite and assign it to the action.

Alternatively, you can drag the sprite asset from the Asset Browser and drop it into the “Sprite” field:

undefined

The “Frame” field is the sub-image to switch to, and we're keeping it at 0 so the sprite animation starts from the beginning.

In-Air State

The jump animation will now play when the player bounces off a window, however when that animation ends, we want it to transition into its “in-air” sprite. For this we need a new event, so click on “Add Event” in the player’s Events window, go under “Other” and select “Animation End”.

undefined

This event is as simple as it sounds: it runs when the player’s current animation ends. We want to use this event to check if the player’s jump animation has just ended, and in that case, change the sprite to spr_player_air.

Search for the “If Variable” action in the Toolbox and drag it into the event. We’re going to use this action to check the variable sprite_index, which stores the sprite that the instance is currently using. So set the “Variable” field to sprite_index and the “Value” field to spr_player_jump.

undefined

This condition now checks if the player’s sprite is spr_player_jump, meaning that it’s playing the jump animation. Because of the event we are in, we know that the jump animation has ended, so we’re going to switch to the “in-air” state instead.

In the Toolbox, search for the “Set Sprite” action and drop it to the right of the “If Variable” action, so it’s controlled by that condition. In the Sprite field, enter “spr_player_air” or press the button next to it to open the Asset Explorer and find the asset there.

undefined

This event is now finished, and will change the player’s sprite to spr_player_air when the spr_player_jump animation ends.

Tip: You can use this same technique anywhere to create transitions between two sprites

Fall State

The fall state plays as the player is falling. We’re going to check this in a new event and change the sprite to spr_player_fall.

In the Events window for obj_player, click on “Add Event”, go under “Step” and select the “End Step” event. This event runs after the Step event, so like that event it also runs once per frame, and we’re using it to make our object more organized (instead of putting everything into the one Step event).

To go into the fall state, the vspeed (vertical speed) of the player needs to be greater than 0, so we’ll use this as our condition. In the Toolbox, search for the “If Variable” action and drop it into the event. Set the “Variable” field to vspeed, the “Is” field to “Greater” and the “Value” field to 0.

If this condition is met we want to change the sprite, so look for the “Set Sprite” action and attach it to our “If Variable” action. Set the “Sprite” field to spr_player_fall or use the button next to it to find it through the Asset Explorer.

undefined

This will now set the player’s sprite to spr_player_fall whenever it’s falling down. That’s all three states down now, so let’s run the game and play around:

undefined

The player now animates between its three states! You may find that the player jumps too easily now, and that is because the mask of the instance is not consistent. Let's work on that now.

Masks

In the previous part of the tutorial, we edited the mask of the player sprite (spr_player_air) so it only covers its lower half:

undefined

Now that we’ve added two more sprites for the player, the other sprites are not going to use this mask. This means that the hitbox for the player will be inconsistent as it changes with the sprite. To fix this, we could edit the masks for the other player sprites to look the same, but luckily we don’t have to do that.

We can assign a sprite to an object as its “mask”, so the mask from that sprite will be assigned as the permanent mask (hitbox) for that object. This means that even if the sprite for that object changes to something else, the mask that we set will be kept.

Let’s go into obj_player, and find the “Collision Mask” option in its Object Editor. You will see that it says “Same As Sprite” which means that the mask from the active sprite is used. We want to change this so it uses a fixed mask, so click on it to open the Asset Explorer and look for spr_player_air. Select that sprite when you’ve found it, and it will now be used as the player’s mask at all times.

undefined

Spawning Civilians

The main part of our game’s loop is the ability for the player to rescue civilians, so we’re going to work on that now. The windows should randomly spawn civilians on them that the player can “collide” with and rescue.

Importing Sprites

We’re going to import three separate civilian sprites, one of which will be randomly selected to spawn on a window, giving the game some variety in its visuals.

In your Asset Browser, right-click on the “Sprites” group and select “Create Group”. This will create a new group that can be used to store assets, and we want to use this for civilians -- so name it “Civilians”.

undefined

In this new group, create a new Sprite asset and name it “spr_civilian_0”. In the Sprite Editor, click on "Import" and go to the tutorial's art assets. In the "Civilians" folder you will find "spr_civilian_0a" and "spr_civilian_0b", which are frames for this civilian's sprite, so select both files and import them.

Set the origin to Bottom-Centre. You will also need to adjust the "Fps" (animation speed) in the top-left corner of the Sprite Editor, as this animation only has two frames and will be too fast by default. You can set it to 4, or any other speed you prefer.

undefined

Now repeat this for “spr_civilian_1” and “spr_civilian_2”, importing two frames for each, adjusting the Fps and setting the origin to "Bottom Centre".

Since the origins for these sprites are set to “Bottom Centre”, and the origin of our window sprite is directly above its sill, it means that we can place the civilian directly on the window and both sprites should perfectly line up because of their origin points:

undefined

Civilian Object

While there are three separate civilian sprites, there will only be one civilian object that will be assigned a random sprite to display. Go into the “Objects” folder in your Asset Browser, and create a new Object asset called “obj_civilian”. Assign the spr_civilian_0 sprite to it.

Before we program any of its behaviours, we need to make it a child of obj_move_parent so that it moves down with the view. Click on the “Parent” button, and in the window that opens, click on “No Object” to open the Asset Browser. Look for obj_move_parent and select it as the parent.

undefined

We now have one civilian object, but three sprites for it. We’re going to make it so the object selects a random sprite from the three whenever it is created.

In the Events window for obj_civilian, click on “Add Event” and select “Create”. Here we want the object to choose between the three sprites available, and for that we’re going to use the “Choose” action. Search for it in the Toolbox and drag it into the event.

This action lets you specify multiple options, and selects one of them at random. In the first “Option” field, enter spr_civilian_0. Then click on the undefined plus sign to the left of the action to add a new option, and set that to spr_civilian_1. Add another option in the same manner and set that to spr_civilian_2.

One of these options will be selected and applied to the variable in the “Target” field. We want it to be applied to the instance’s sprite, so that a random sprite is selected and applied directly to the instance, so we’re going to enter sprite_index in the “Target” field.

undefined

This will now select a random sprite from our given options and apply that to the instance.

Cleaning Up

When a window instance goes out of the room, we simply pull it out and place it at the top, so it appears again and the game keeps going. This will not happen with a civilian instance, as we don’t want it to appear again if it has gone out of the room (since we will keep spawning new civilians). This means that we need to destroy a civilian once it has disappeared.

To do this, we’re going to add the Step event to our civilian object. Once you have added it, go into the Toolbox, search for “If Variable” and drag it into the event. Here we want to do something that we have previously done in the window object -- to check if the instance is below the room. Set the “Variable” field to y, the “Is” field to “Greater” and the “Value” field to room_height + 350.

This will check if the Y position of the instance is greater than the room’s height, with an additional margin of 350 pixels as the civilian sprite is quite large. In this case we simply want to destroy the instance, so search for the “Destroy Instance” action in the Toolbox, and drop it to the right of the “If Variable” action so it’s controlled by that condition.

undefined

Spawning

We’re going to spawn civilians with the windows, however we are going to use a new layer for this to make sure that they are drawn between the windows and the player. Go into the rm_game room and in the Layers panel on the left, create a new Instance Layer and name it “Spawns”. Make sure that it’s placed between the “Instances” and “Player” layers:

undefined

For spawning civilians, let’s go into obj_window and open the Step event. Here we already have one condition that checks if the window is below the room, which controls a chain of actions for respawning the window. We’re going to add more actions in this same chain for spawning a civilian on the window.

We need a random number generator to control if a civilian will spawn or not. In the Toolbox, search for the “Get Random Number” action and drop it into the event, under the same chain as the previous actions (below “Jump to Point”). Set the “Type” field to “Integer”, the “Minimum” field to 0 and the “Maximum” field to 1. We want the result of this action in a new temporary variable, so set the “Target” field to chance (as the variable’s name) and enable the “Temp” checkbox.

undefined

This will create a temporary variable named chance which will be either 0 or 1 (we will increase the maximum limit in the next part, but for now these are the only possible values). We will only spawn a civilian on the window if this number is 0, so we’ll need a condition for this -- but instead of using the usual “If Variable” action, we’re going to make use of a “Switch”.

A Switch lets us specify a variable at the top, and then execute multiple “cases” for it. If the specified variable is equal to any one of the given cases, the actions under that case are going to run. See the following visual:

undefined

Right now we have only one case to check (if chance is equal to 0) however in the future we will add more cases, which is why the switch is perfect for evaluating the same variable multiple times.

In the Toolbox, search for “Switch” and place it into the same chain of actions. Set the “Value” field to chance. Back in the Toolbox, search for “Case” and add that action into the “Switch” action. In this new action, set the “Constant” field to 0.

undefined

You can now attach new actions to this “Case” action, just like with a “If Variable” action, and those actions will only run if the chance variable is equal to 0.

If this case is true, we want to spawn a civilian on the window. In the Toolbox, search for “Create Instance” and attach that action to the Case action. This action lets us create an instance of an object, so we’re going to use this to spawn a civilian.

Set the “Object” field to obj_civilian (or press the button next to it to open the Asset Explorer and find it there). We’ll create it at the same position as the window, so enable the “Relative” checkbox for both “X” and “Y” and leave their values at 0. Set the “Layer” field to “Spawns” (including quotes) as the name of the layer where our instance will be created.

undefined

This will create a civilian instance on the window, however we also need to take care of one more thing: the window is closed by default, so we need to open it by using its second frame.

undefined

The first frame of our spr_window sprite has the closed window image, which is used by default. We want to assign the second frame to the window when a civilian is spawned. We can use an action to achieve this, so in the Toolbox, search for “Set Sprite” and drop it into the action chain, under “Create Instance”.

Set the “Sprite” field to spr_window, which is the sprite that the window is already using -- we’re not changing that. What we are changing is the frame. We want to assign the second frame to the window, and as frame numbers start at 0, the second frame will be 1. Set the “Frame” field to 1 and this should do exactly what we want!

There is one final change we need here: when the window respawns, it should revert back to its default frame. In the Toolbox, search for “Set Sprite” and drop it above the Switch action (so it's independent of it). Set the “Sprite” field to spr_window and leave the “Frame” at 0. This makes sure that the window always resets to its first frame, and then it can be changed by the Switch action below.

undefined

If you run the game now, you will notice random civilians spawning on windows and moving down with the view!

undefined

Rescuing Civilians

We’re going to make the player able to rescue civilians. The player will simply collide with a civilian instance, at which point the civilian will fly off using a parachute and disappear.

We need to import images for every civilian with a parachute, which will be displayed after they are rescued. In your Asset Browser, you will have a “Civilians” group under “Sprites”, which we created in the previous section. Create three new sprites in it and import images for them from the tutorial’s assets:

  • spr_civilian_rescued_0
  • spr_civilian_rescued_1
  • spr_civilian_rescued_2

Make sure that the origin for these sprites is set to “Bottom Centre”, so they match with the regular civilian sprites.

undefined

Now to program its rescue animation, let’s go into obj_civilian and open its Create event. Here we’re going to create a variable to store whether this civilian has been rescued or not. In the Toolbox, search for the “Assign Variable” action and drop it into the event. Set the “Name” field to rescued, which will be the name of our new variable, and the “Value” field to false.

What we’re creating here is called a “boolean” variable. This can either be true or false, telling us whether something has happened or not. Since rescued is false by default, it means that the civilian hasn’t been rescued. We’ll set this to true when we rescue it, and we check its value at any time to know the civilian’s state.

Help, Player!

The civilian now needs to check whether the player is colliding with it. In obj_civilian’s Events window, click on “Add Event”, go under “Collision”, then “Objects” and select obj_player. This will add a collision event between the civilian and the player.

This event needs to have a condition at the top, to make sure that the civilian has not been rescued yet. In the Toolbox, search for “If Variable” and drag it into the event. Set the “Variable” field to rescued and the “Value” field to false. All further actions added to this event should be attached to this action.

To make sure that this event only runs once, we need to set the rescued variable to true. Search for the “Assign Variable” action and attach it to the “If Variable” action. Set the “Name” field to rescued and the “Value” field to true.

undefined

This makes sure that the civilian can only be rescued once, as the rescued variable will be true after this and not false.

Now we want to make the civilian jump up and fall down, so we’re going to give it an upward push as well as enable gravity. Add the “Set Speed” action into the same chain as the previous action. Set the “Type” to “Vertical” and the “Speed” to -18.

For gravity, search for the “Set Gravity Force” action and drop it in the event. Set the “Force” to 0.5 (we’re using a low gravity value since the civilian is using a parachute).

undefined

The civilian will now jump off the window, but it also needs to display the correct "rescued" sprite from the ones we imported. Since there are three different kinds of civilians, we’ll use a Switch block to assign the correct sprite when it is rescued.

In the same event, search for the “Switch” action and drag it into your action chain. Since we need to check what sprite the civilian has, set the “Value” field to sprite_index.

Now it’s time to add cases to this Switch, so find the “Case” action in the Toolbox and drop it into the Switch action. In the “Constant” field, enter spr_civilian_0. If that is the civilian’s sprite, we want to switch to its rescued equivalent, so search for the “Set Sprite” action and attach it to your Case action. In this new action, set the “Sprite” field to spr_civilian_rescued_0 (or find it through the Asset Explorer button).

We need to do the same for the other civilian sprites, so add cases for both of those sprites (spr_civilian_1 and spr_civilian_2) and switch them to their rescued equivalents (spr_civilian_rescued_1 and spr_civilian_rescued_2). It should look like the following:

undefined

Using these Switch and Case actions, we’re changing the civilian’s sprite depending on the three possible sprites that it can have.

Tip: This technique can be used anywhere to perform different actions based on different values of a variable.

If you run the game now, you should be able to rescue any civilians that spawn. When the player collides with a civilian, that civilian gets a parachute and falls off the window, and once it’s below the room it gets destroyed because of its actions in the Step event.

undefined

Depth

In the GIF above, you can see that a rescued civilian appears below the player, since the "Spawns" layer is below the "Player" layer. To make it appear above the player after it has been rescued, we can change its "depth" value.

The depth controls which instance appears above others, and is usually tied to the layer. However we can change it manually using an action to change the order of appearance. If an instance has a lower depth value then it will appear above instances with higher depth values -- see it as the instance's distance from the player's eyes.

In the obj_civilian object, go to its Collision event with obj_player, and above the Switch action add the "Set Instance Variable" action:

undefined

Here we are changing the depth of the civilian instance to obj_player.depth - 10. This means that its depth will be 10 units less than the player's, and so will appear above it! Test the game now and you will see that all rescued civilians now draw above the player, making the game feel more realistic.

Rescue Score

We’re going to add a score system to our game, so we can count how many civilians the player has rescued and display that on the screen.

Set Up

First of all we need to import a new image to display the rescue score on the HUD. In your Asset Browser, go into the “Sprites” group and create a new sprite asset called “spr_score_card”. You will find this image in the tutorial’s art assets under "UI", which you can import through the Sprite Editor. Set its origin to "Middle-Centre".

undefined

We need another visual addition to the project, but this time it’s not a sprite but a font. Since we’ll be drawing the player’s score as text, it’s best to have a custom font that you can personalize to fit the look of your game.

In the Asset Browser you will find a “Fonts” group. Right click on it, go under “Create” and select “Font” (this is an alternative to creating assets through the "Create Asset" menu, and both are fine to use). This will create a new Font asset that we’ll call “fnt_score”.

Note: The fnt_ prefix indicates that it is a Font asset.

You will see the Font Editor open up in your workspace, where you can edit the look of your font. Under the asset’s “Name” field, you will find the “Select Font” option which allows you to choose a font from the ones installed on your computer. Under the “Presets” section in the middle, you can assign a style and size to the font.

Tip: The font we've used in this tutorial is Poetsen One.

undefined

Go ahead and choose whatever font you like, and set the size to be somewhere around 36 as that works best for our example. When you are done editing your font, you can close the Font Editor and proceed with the tutorial.

Global Variables

We know that we can create a variable using the “Assign Variable” action, however that creates an Instance Variable. Such a variable is only available in one instance and other instances cannot access it. We cannot use this to create our score variable, as we want all instances to be able to access and change it. So we’re instead going to use Global Variables.

A Global Variable is accessible through all instances, which is ideal for our score as there will be a separate object to draw it, but it will be modified in a different object.

Let’s create our player’s rescue score variable. Go into obj_player and open its Create event. In the Toolbox, search for the “Set Global Variable” action and drop it into the event. This action allows you to create (or change) a global variable. Set the “Name” field to score_rescue, which will be the name of our new global variable, and set the “Value” field to 0 (there is no score by default).

undefined

Note: The undefined plus button to the left of the action is used to add another variable to the same action. We will make use of this later in this tutorial to create a new score type!

Adding Score

We will increase this score variable by 1 whenever the player rescues a civilian. Since that happens in the civilian object (obj_civilian) let’s open it, and go into its Collision event with obj_player. In the Toolbox, search for “Set Global Variable” and drag that action anywhere into the “If Variable” action’s chain so it’s controlled by that condition -- I’ve added it at the top:

undefined

As you can see in the image above, we’re setting the score_rescue variable to 1 with the “Relative” checkbox enabled. This will add 1 to the score value, so the player’s rescue score will go up each time it rescues a civilian.

Score Object

We have a score variable now that goes up every time a civilian is rescued. All we need to do now is to draw it on the screen, so the player can see how good they are!

In your Asset Browser, find the “Objects” group and create a new Object asset here. We’ll call this “obj_score_rescue” as this will draw our rescue score. Apply the spr_score_card sprite to this object.

We want this object to draw the score value. This is something that happens each frame, just like the Step event, however that event does not support drawing. For this purpose we have an event called “Draw”. In the Events window, click on “Add Event”, go under “Draw” and select the “Draw” event.

undefined

This event runs every frame, and allows us to draw anything (sprites, text, shapes, etc.) to the screen. We need to draw our score text, however before we do that, there is something important to take care of.

Once you add a Draw event to an object, its instances will not be drawn anymore. This is because GameMaker has now given you control over the object to draw it in any way you like, however we want it to draw normally as it would by default. To achieve this, search for “Draw Self” in the Toolbox and when you find that action, drag and drop it into the event.

undefined

With this action in the event, the instance will be visible again, so let’s proceed to drawing the score text over it.

Drawing Text

Before drawing the score text, we need to make sure that it uses our new font (fnt_score). In the Toolbox, search for “Set Font” and drop that action into the event. Set the “Font” field to fnt_score (or use the button to the right and find the asset through the Asset Explorer). Any text we draw after this action will now use that font.

The main action that we’ll use to draw our score is called “Draw Value”. Search for it in the Toolbox, and drop it into the event. Make sure that it comes after the “Draw Self” action, otherwise the text will be hidden behind the sprite, and also make sure that it comes after the “Set Font” action so our custom font is used to draw the score.

undefined

The “Caption” field is the text that draws before the score. We’ll set this to “Rescued ” including the space at the end, to add some distance between that text and the score value.

Note: Make sure to include the quotes with the “Rescued ” text as shown in the screenshot. Such a text value is known as a “string”.

The “Value” field is the actual value that needs to be drawn, which we’ll set to global.score_rescue. We’re using our global variable in a non-global action, so we need to specify the global. prefix, otherwise it won't be able to find the variable.

The “X” and “Y” fields take the position where this text will draw. We want to draw it at the instance’s position, so we’ll leave them at 0 and enable the “Relative” checkboxes for both.

This will draw the text now, however it is not ideal. By default, the text is drawn with a “Left-Top” alignment meaning that it wouldn’t be centered on the instance.

undefined

Let’s first change the alignment to “Centre-Middle”. In the Toolbox, search for “Set Text Alignment” and drop that action before the   “Draw Value” action. This action allows you to change the horizontal and vertical alignment of your text. Click on the button to the right of the “HAlign” field and select "Center”, then click on the button next to the “VAlign” field and select “Middle”.

This action will change the global alignment, meaning that any text drawn after this will use Center-Middle alignment. This works well for us now, but to make sure that this change doesn't affect any other text in our game, we'll reset these values after drawing our text.

We’ll use this same action again to reset the alignment back to default. Add another “Set Text Alignment” action (you can find it under “Recently Used”) below the “Draw Value” action. Leave the values as they are so that they are reverted to default.

undefined

Because of the order of our actions, the following will happen:

  1. The alignment will be set to Centre-Middle
  2. Our text will be drawn using that alignment
  3. The alignment will be reset to default

This is a fairly common technique in GameMaker Studio 2, where you change a global property, draw something, and then reset that property to default.

HUD Layer

To make the buttons visible, we’re going to place them in our room. In your Asset Browser, go into the “Rooms” group and open rm_game. Go to the Layers panel on the left and create a new Instance Layer called “HUD”. Place it at the very top so that the HUD instances appear above everything else.

undefined

Drag the obj_score_rescue button into this layer and place it wherever you like, preferably in the top-left corner. Run the game, and you will now see your rescue score!

undefined

Height Score

We’re now going to add another score type to record how high the player has climbed.

Go into obj_player and open its Create event. Find the already-existing “Set Global Variable” action, and click on the undefined plus button to its left to add a new global variable. Set the “Name” for this variable to score_height and leave its value at 0.

undefined

This variable will store the height score, so the player can tell how far they have climbed. To increase this score value, we’ll go into the player’s Step event, which is where we scroll the view. We’re going to increase the score value here as well.

In the Toolbox, search for the “Set Global Variable” action and drop it into the action chain. Set the “Name” field to score_height and the “Value” to downspeed / 100. Since we want to increase the score variable, enable the “Relative” checkbox.

undefined

We are increasing the score_height value by the downspeed value divided by 100. We’re dividing it by 100 so that the score stays relatively low: for every 100 pixels climbed, the score will only go up by 1.

Drawing Score

We want to draw the height score in its own object, just like we did with the rescue score. In fact, we’ll simply duplicate the rescue score object to save time.

In your Asset Browser, expand the “Objects” group and find obj_score_rescue. Right click on it and select “Duplicate”. This will create a new object asset, which we’ll name “obj_score_height”.

undefined

Find the Object Editor for obj_score_height in your workspace (or double click on the asset to open it). Since we’ve duplicated the previous object, it will already have the same Draw event for drawing the score. Open this event so we can change what score variable it draws.

Find the “Draw Value” action in this event. Change the “Caption” field to “Height ” (including the quotes and the extra space), then change the “Value” field to round(global.score_height).

undefined

For the rescue score value, we simply used global.score_rescue, however for the height score, we are using round(global.score_height). Why is that?

round() is a function that rounds a value, so for example, 0.1 becomes 0, 1.7 becomes 2 and so on. If you remember, we made the height score go up by downspeed / 100, which is a decimal value. This means that the score will also be a decimal value, and to display it as an integer instead, we wrap it in round().

The following image shows the score drawn with and without rounding, and you can tell why we’re rounding the value as it looks much better:

undefined

Now open your rm_game room, select the “HUD” instance layer and drop the obj_score_height object anywhere you like, preferably in the top-right corner. You will now see both scores in the game, and it'll be much more exciting to play!

undefined

Bonus: Jump Effect

As a bonus, we’re going to show a visual effect whenever the player jumps. Let’s import a sprite first: go into the “Sprites” group and create a new Sprite asset called “spr_jump_effect”. In the tutorial's art assets, in the "Animations" folder, you will find an image called spr_jump_effect_strip25 which you can import through the Sprite Editor. This file has _strip25 at the end of its name because it's a 25-frame animation, and GameMaker will use this information to automatically divide it into 25 separate frames (or sub-images):

undefined

Set the origin to “Bottom Centre” so it’s easier to place at the player’s foot when it jumps (which is on the window sill).

In the “Objects” group, create a new object called “obj_jump_effect”. Assign the spr_jump_effect sprite to it. We want this object to move down with the view, so open its “Parent” menu and assign obj_move_parent as its parent object.

undefined

We will create an instance of this object whenever the player jumps, and it should be destroyed when its animation ends. For this we’re going to use a new event: click on “Add Event”, go under “Other” and add the “Animation End” event.

undefined

In the Toolbox, search for the “Destroy Instance” action and drop it into the event. This will now destroy the jump effect when its animation ends, meaning that it will play only once after its instance is created.

Now to show this jump effect, let’s go into obj_player, and open its Collision event with obj_window. Here we have an “If Variable” action which creates a new chain of actions, and we want to add a new action to this chain.

In the Toolbox, search for the “Create Instance” action and attach it to the “If Variable” action so it’s placed in its chain. Set the “Object” field to obj_jump_effect (or find it through the Asset Explorer button on the right).

Horizontally, we want to place it exactly where the player is, so enable “Relative” for the “X” field while leaving its value at 0.

Vertically, we want it to be placed on the window, as the player is jumping off it. If we used “Relative” here then it would be created at the player’s chest by default, which is something we don’t want, so make sure that “Relative” is disabled for the “Y” field. In the same field, enter other.y.

undefined

We will learn more about other in the next part, but in this case it refers to the window instance that is colliding with the player (as that is the “other” instance in this collision). This means that the jump effect's Y position will be on the window, where the player has stepped.

Finally, set the “Layer” field to “Player” so that the effect is created in the same layer as our player, and then run the game to see your jump effect:

undefined

Summary

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

  • You can change the sprite after playing an animation once using the Animation End event
  • You can create a new instance in the game using the “Create Instance” action
  • You can use the Switch action to do something different based on a variable’s value
  • You can draw text in the Draw event using the “Draw Value” action
  • Remember that you need to use “Draw Self” to draw the instance itself
  • And finally: You are amazing!

In the next part, we’re going to add fire to the windows and give the player the power to put out those fires by shooting foam. We’ll also add sound effects to give our game some polish.

Next: Fire Jump Tutorial - Part 3