Welcome to the Fire Jump tutorial! Thisseries will take you through developing an infinite platformer game inGameMaker using GML Visual. You will learn how to make aplayable character, generate infinite obstacles, build a solid game loopalong with menus and much more.
Thistutorial will take you through the process of making the game fromstart to finish, step-by-step, and also introduce you to the variouselements of GameMaker. Everything is explained in an easy tounderstand manner, so you can follow this tutorial even if you havenever used GameMaker before, and there is enough usefulinformation for intermediate users to enjoy as well.
Thisis Part 1 of a 4-part series, all of which are available for free onthis site.You can refer to the index pageto navigate to the other parts.
Here is a video version of this tutorial:
Goal
Ourgoal is to create a game where you control a firefighter as they scale abuilding by jumping on randomly generated windows, rescuing trappedcivilians while putting out fires along the way. The game will consist ofthree different screens:
- Title screen
- Main game
- Game over screen
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.
Overview
This page is divided into the following sections:
- Starting a Project
- Creating and Importing Assets
- The Game Room
- Events and Actions
- Player Controls
- Bouncing Off Windows
- View Scrolling
- Spawning Windows
- Street Area
Starting a Project
Let’s start by creating a new project which we’re going to use to develop our game.
Open GameMaker and click on “New”, then select "New Blank" as we'll be starting with a blank project.
Enter a name for your project (you can name it “Fire Jump”)and click on "Let's Go!".
After creating your new project, you will see it open up in GameMaker:
TheAsset Browser is where we create and manage all of our assets, whichincludes all the art (sprites), objects, rooms, and other assets that weuse in our game. The Workspace is where we edit those assets andprogram our game.
Creating and Importing Assets
Let’sstart by creating a sprite, which is an image asset that can be usedfor in-game objects and animations. Select the Sprites group using the left mouse button, go to the “Create Asset” menu at the top anddouble click on “Sprites” to create a new sprite asset. Name this asset“spr_player_air” -- we’re going to use this as our player’s “in-air”image.
Note:The “spr_” prefix denotes that the asset is a sprite. Including thisprefix is not required, however doing so will result in easilyrecognizable asset names.
Inthe Workspace on the left, you will see a Sprite Editor open up. Hereyou can rename the sprite, change its size and use the “Edit Image”option to open the Image Editor, which will allow you to draw on thatsprite.
We’regoing to use the “Import” option to load an external image file, whichwill be imported as our player’s in-air sprite. Click on Import,navigate to the assets folder that you downloaded and from a Character folder, select “spr_player_air”.
Youwill see the imported image in the Sprite Preview pane. Here we need toadjust its “origin”, which is the point on the sprite that it rotatesaround. For this sprite we want its origin to be at the center, so openthe drop-down menu in the top right corner of the Sprite Editor (whereit says “Top Left”) and change it to “Middle Center”.
Side-note on Origin:Theorigin is not only used for rotation, but also as the central point ofan object to which its location points. You will learn more about theorigin point as you progress through this series.
Let’simport the images for the window that the player will jump on. Selectthe Sprites group in the Asset Browser, go into the Create Asset menuand add a new sprite. We’ll call this “spr_window”. In the SpriteEditor, click on Import, and navigate to the sprites folder for thistutorial. We’re not going to import just one image but three: these arevariations of the same window which we will show based on what kind ofwindow it is!
In the "Building" folder, selectthe files “spr_window_0”, “spr_window_1” and “spr_window2”, then click“Open” which should import those three images into the same sprite assetas “sub-images”!
Note:If the order of your sub-images is not the same as shown above, please drag the sub-images around in the frames section of the Sprite Editoras this order will be important going forward.
Sub-imagesare usually used for animated sprites, which we will do for anothersprite in this tutorial — however, this is not an animation, so we’regoing to set the FPS at the top-left corner of the Sprite Editor to 0.Doing this ensures that your sprite doesn’t animate when it’s used inthe game.
Wealso need to set an origin point for this sprite. The window doesn’tmove or rotate, so the origin should not matter in that regard, howeverwe will use the origin point to spawn civilians and fire on the window.To make sure that they are placed right on top of the window sill, weneed to place the origin point atop the sill as well, right in the middle. Drag the origin pointer from the top-left corner of the image and place it here:
Withthat done, we need to import one final image for this part of thetutorial. Just as we did with the previous sprites, create a new onecalled “spr_brick_tile” and import the file with the same name from thetutorial’s sprites folder. This will be the brick image that is tiled asthe game’s background.
Wehave imported three game elements: the jumping player, the window thatthe player will jump off, and a brick sprite that will be tiled in thebackground. We’re going to add them to our game, however these are onlyimages, and to program the behavior of our player and windows, we needto create “objects”.
Objects
Anobject can act as a visual part of the game that has a sprite attachedto it (to control how it appears) and a list of events (to control whatit does). Our player and window will be objects, and they will use thesprites that we have imported. However, objects can also be used asnon-visual controllers that have no sprite attached, but still have alist of events performing their behaviors in the background.
An object can act as a visual part of the game that has a spriteattached to it (to control how it appears) and a list of events (tocontrol what it does)
Let’screate our first two objects. Select the “Objects” group in the AssetBrowser, go into the “Create Asset” menu at the top, and create twoobjects: "obj_player"and "obj_window".
Inthe workspace, you will see the Object Editor open up for each objectyou have created. Under the “Sprite” section of the Object Editor, youcan click on “No Sprite” to open the Asset Explorer, where you canselect a sprite to be assigned to the object. So go ahead and use thesprite spr_player_airfor obj_player, and spr_windowfor obj_window.
Note: See how our naming convention makes it easier to identify the assets, as we instantly know that spr_player_airis the player sprite, and obj_player is the player object.
The Game Room
Nowthat we have the basic objects that we need, we’re going to set up ourgame “room”. A room is an asset that serves as the game’s screen, so forexample, you can have one room for the main menu and another for the game. You can easily switch between rooms and the currently activeroom will appear in the game’s window.
Inthe Asset Browser, open the “Rooms” group and you will see that thereis already a room present. Let's rename it first -- right click on it and select "Rename" (or press F2) and name itrm_game (since our game will take place here).
Double click on the room asset to open the RoomEditor:
Onthe left you have the Room Properties, and in the centre the main roomarea. This space is what you will see when you run your game, and thisis where we want our game to take place.
Firstof all, let’s adjust the size of this room, which will be theresolution of our game. Go into the Room Settings at the bottom-leftcorner of the IDE, and set the width and height to 1080 and 1920respectively.
Note:We’reusing a resolution of 1080x1920 instead of 1920x1080 as we want to use amobile-like aspect ratio. This will enable you to easily port this gameto any mobile platforms later on!
Tiled Background
Nowthat we have an appropriately sized room, let’s give it a background soit’s not blank anymore. Go into the Layers section in the top-leftcorner of the Room Editor, and you will see the two default layers:“Instances” and “Background”. We’re going to look at the Instances layersoon, but let’s first assign a background image to our room.
Selectthe “Background” layer, and just below the Layers section you will seethe Background Layer Properties. Click where it says “No Sprite”, whichwill open up the Asset Explorer (similar to the one we used in theObject Editor). Here you can select a sprite to assign as the room’sbackground, so go into the Sprites group and select spr_brick_tile.
Youwill notice that the tile appears in the room, but only in its top-leftcorner. To tile it all over the room, go into the Background LayerProperties and enable both “Horizontal Tile” and “Vertical Tile”. Doingthat will fill the room with the brick tile!
Note: If you see a grid overlay in the room, you can press G to disable it.
Now let's see how we can place objects in rooms.
Instances
Whenyou place an object in the room, it becomes an “instance” of thatobject. This means that you can have one object asset and place multipleinstances of it in a room, with each instance having its own uniqueproperties.
Instancesare placed in Instance Layers, and the “Instances” layer that ispresent in the Layers section is one such layer. Select that layer, anddrag in the window object from your Asset Browser.
You have a window instance now! Drag in some more and create a line-up of windows on the building for our player to climb on.
Whereis our player, though? Let’s add it in as well, but in a new layer.Create a new Instance layer using the buttons at the bottom of theLayers panel, and name it “Player” (press F2 or select “Rename Layer” inthe right-click menu). Make sure that it is placed above the“Instances” layer, and if it’s not, you can simply drag it to the top.
Whyare we creating a new layer? The order of the layers determines whenits instances are drawn, so placing a layer higher in this list ensuresthat it is drawn above the other layers. This means that our “Player” layer will be drawn abovethe “Instances” layer, to ensure that the player instance appears above the windows.
Drag in the player object into the “Player” layertocreate an instance, and place it somewhere around the bottom-centerarea of the room. Your room should be looking something like this now:
Now that our room is ready, let’s see how we can program the behavior of our objects.
Events and Actions
We’regoing to take a look at the two most important features when it comesto programming with GML Visual: Events and Actions.
Actionsare used to program your object -- you can use an action to tell theobject to move, jump, rotate, destroy itself, and so on.
This is a pretty simple concept, however there is one question that makes it a little complicated: when do we run an action?
Asa solution to that problem, GameMaker has “events”. You will see anEvents window in the Object Editor, with an “Add Event” button thatopens up a list of all the available events:
Anyof these events can be added to an object, and any number of actionscan be placed inside an event. Each event has its own behavior as towhen it runs!
Forexample, the Create event runs when the instance is created, whichmeans that it runs only once. Then there is the Step event which runsevery frame of the game, and since there are 60 frames in a second bydefault, that event runs 60 times in one second.
Thereare also input events that run based on keyboard and mouse input. Thisenables us to easily create controllable characters by adding actions tosuch events!
Player Controls
We’re going to program our player to do two things:
- Automatically jump on creation
- Move left or right depending on keyboard input.
Let’sstart with the first one! Go into the obj_player object, and in theEvents window, click on Add Event. In the list that opens, click onCreate to add that event into the object.
When you select your event, you will be asked to choose between GML Visual and GML Code:
Select GML Visual, and make sure to enable "Don't ask again for this project". Hit "OK".
Doing this will open the eventin a new window, which is where you can add actions:
The“Toolbox” panel to the right of that window allows you to search foractions and add them to your event. We added the Create event so wecould ask the player to jump when it’s created, so let’s find an actionfor that! Scroll to the “Movement” section of the Toolbox and find the “SetSpeed” action (or just search for it through the Search field at the top).Once you’ve found the action, drag and drop it into the empty space onthe left:
Usingthis action, we can tell the object’s instance to move in any givendirection. We want it to have a vertical speed in the beginning so itcan jump up, and to achieve that, we need to set the “Type” of thisaction to “Vertical”. Before we give it a speed however, let’s look athow movement works.
Moving Around
Ourroom has two dimensions, one horizontal and the other vertical -- henceresulting in a 2D game. We use these two dimensions to move ourinstances around the room.
Thehorizontal dimension is called the X axis, and the vertical dimensionis called the Y axis. Coordinates are usually written in the (X, Y)format, so for example, if an instance is at 20 pixels on the X axis and10 pixels on Y, it would be written as (20, 10).
Roomcoordinates start from the top-left corner of a room, which is (0, 0).The X value increases as you move right, and the Y value increases asyou go down.
This means that to move an instance, we need to add or subtract its position on the X or Y axis.
- +X: Adding to the X axis moves it to the right
- +Y: Adding to the Y axis moves it down
- -X: Subtracting from the X axis moves it left
- -Y: Subtracting from the Y axis moves it up
We’re going to use this technique to move our player on both axes, so let’s continue with implementing our initial jump.
Tip:Youcan see the coordinates at any point in the room by hovering your mouseon that point and reading the coordinates at the bottom of the RoomEditor.
Jumping
Note:When we’re programming an object in this tutorial, I will be referringto it as an “instance”, because any actions in the object will becarried out by its instance in the room.
Aftersetting “Type” to “Vertical”, we need to specify a speed for theinstance’s vertical axis. Since we need to subtract from the Y axis tomove it up, we’re going to enter -35 as the speed.
Thisaction will make our player move up at a speed of -35. If you run thegame now, you will only see the player moving up, as we haven’timplemented gravity to make it fall down. So, let’s do that!
To run the game, press F5 or click on the play button at the top of the IDE
Weneed to use the “Set Gravity Force” action, which is present in the“Movement” section of the Toolbox, same as the previous action. Keep inmind that you can always search for the action, and once you have foundit, drag it into the event.
Theforce of gravity can simply be 1, but feel free to changethis (and the initial vertical speed) as this is your game and you canmake it feel exactly how you want!
This is what your Create event should look like now:
Runningthe game now will show the player jumping and then falling down. Whatwe need now is a way for it to move horizontally and bounce off thewindows.
Note: You can pan around the event space by holding the middle mouse button, or by holding the Alt key if you're usingLaptop Mode. This will come in handy if you have a lot of actions in one event.
Horizontal Movement
Wewant the player to move horizontally using the left andright arrow keys. As mentioned in the part on Events & Actions,GameMaker has events for keyboard & mouse input. We’re going to use acouple of them for our left and right arrow keys.
Inthe Events window for obj_player, click on “Add Event”, go under “KeyDown” and select the “Left” event. This will add an event called “KeyDown - Left” to your events list. Repeat the same action but this time,select the "Right" event. Now along with the Create event, you will havetwo new events:
Theseevents are for the left and right arrow keys respectively. In eachevent we are simply going to modify the X position of the instance so itmoves horizontally.
Gointo the “Key Down - Left” event (you can double click on an event toopen its window) and here, search for the “Set Instance Variable” actionand drag it in. This action allows us to modify any one of theinstance’s properties (also known as “instance variables”) and theproperty that we need to modify should be selected from the given list.
Makesure that “X Coordinate” is selected as the variable, and in the“Value” field, enter -15 (negative fifteen). Then, check the “Relative”box so it is enabled.
Becausewe have “Relative” checked, -15 will be added to the instance’s Xcoordinate, and since it is a negative value, the instance will move 15pixels to the left. However, if we hadn’t checked “Relative”, then the Xcoordinate would have been set to -15 meaning that it would immediatelyjump to that point on the X axis. To move the instance, we want its Xcoordinate to be set relative to its current position, which is why we need to enable that option.
We’regoing to do something similar in the “Key Down - Right” event. Add thesame action there (“Set Instance Variable”) and set the “X Coordinate”variable to 15 -- make sure to check the “Relative” option!
This will move the instance 15 pixels to the right.
If you run the game now, you will be able to move the player left or right, but only until it falls down never to appear again…
Bouncing Off Windows
Tokeep the player going, we want it to jump again when it comes incontact with a window. In GameMaker, such an event is known as a“collision”, so we can use that to make the player jump when it collideswith a window.
Clickon “Add Event” in obj_player and go under “Collision”. This will openup a list of objects, where you can select an object for the player tocollide with. Click on obj_window which will add a collision eventwith that object.
Thisevent will run whenever the player comes in contact with a window.We’ll make the player jump when this event runs, but before we do that,let’s learn about masks.
Masks
Eachobject has a mask which is used as its “hitbox”. This mask determineswhether it's colliding with any other instance. By default, the mask isretrieved from the object’s sprite, and luckily the Sprite Editor letsus adjust the mask of a sprite.
Inthe Asset Browser, go into the “Sprites” group and find the spr_window asset, then double click on it to open the Sprite Editor.On the left of that editor you will see a few closed menus, one of whichis “Collision Mask”. If you open it you will see that the image isoverlaid with a transparent, black box, which is simply the sprite’smask:
Bydefault, a sprite’s mask is as large as the sprite itself, which meansthat any area of the sprite is able to collide with other instances.This is usually fine, however we only want our player to be able to jumpon the window’s sill, which is why we need to modify the sprite’s mask.
Underthe “Collision Mask” menu, change the “Mode” option from “Automatic” to“Manual”. Now you will be able to modify the mask’s rectangle in thesprite’s preview panel, by moving it around and changing its size bydragging its corners. Now make sure that it only covers the window sill (it doesn't have to be perfect):
Let’sdo the same for the player. We only want its bottom half to be able tocollide with windows and other in-game elements (to be added later), soopen spr_player, change the mask's Mode to Manual and make it looksomething like this:
You can now close the Sprite Editor windows and return to the obj_player object.
Bounce On Collision
Weadded a new event in the player object for a collision with the window. Let’s add an action in this event -- in the Toolbox, search forthe “Set Speed” action and drag it into the event.
Forthis action, we want to do the exact same thing we did in the Createevent -- give it a vertical speed so it jumps up. Set “Type” to“Vertical” and in the “Speed” field, enter -35. This will make ourplayer jump up whenever it collides with a window!
Tip: You can change this value if you want to increase or decrease the player’s jump power.
Nowrun the game (hit F5 or press the play button at the top of the IDE)and you will see that the player jumps whenever it comes in contact witha window. You are also able to move left and right, so you can now movefreely throughout your level!
Flipping
Youwill notice that the player only ever looks in one direction. Ideally,it should flip to face the direction it’s moving in, and adding such afeature is fairly quick!
Let’slearn a little about scaling first. Every instance in GameMaker has an Xscale and a Y scale, where its X scale controls its horizontal size,and Y scale controls its vertical size. When they are both set to 1, theinstance’s scale is unchanged, however increasing that value will makethe instance larger and decreasing it will make it smaller.
Asyou can see in the image above, setting the X scale to -1 (negativeone) flips it around. We can use this technique to make our player facethe direction it’s moving in.
Gointo the “Key Down - Left” event in obj_player. In the Toolbox, searchfor the “Set Instance Scale” action (found under the “Instances”section) and drag it into the event. This action will allow us to changethe horizontal and vertical scale of the instance.
Ifyou open the spr_player sprite, you will see that our player sprite isfacing right by default. This is its default scale, which means thatwhen the X scale of the instance is set to 1, it will be facing right.This means that we simply need to set its X scale to -1 so that it facesright!
Soin the “Set Instance Scale” action, set “Horizontal” to -1. Leave“Vertical” at 1 as we don’t want to change the instance’s Y scale. Nowwhenever you hold the left arrow key, the X scale of the instance willbe flipped around.
Nowgo into the “Key Down - Right” event, add the same action there, andleave it at its default values. When this event runs, the instance willsimply return to its default scale with the player facing right.
Run the game now, and you will see that the player now faces where it moves!
Note: If your player moves a large distance as it flips, make sure the origin for its sprite is set to Middle Centre.
Note on Display
Dependingon your display, the window might be too large or too small. By defaultyou are not able to resize the game window, so let’s enable that.
Inthe Asset Browser, go under “Quick Access”, expand “Game Options” anddouble click on your platform (Windows or macOS). This will open a newwindow in the workspace with settings for that platform. On the left youwill see a list of menus. Click on “Graphics” and in the options thatopen up to the right, make sure that “Allow window resize” is enabled.
Thereis another option here that might be worth enabling. The “Interpolatecolours between pixels” option makes sure that any scaled graphics appear smooth and that edges between sprites are not jagged. This should be disabled if youare using pixel art, however for our example we want this to be enabledas we are making use of full resolution art.
Tip: You can compare the game's graphics with this option disabled and enabled, and choose the one you like better.
In the following screenshot you can see both options enabled for the Windows platform:
Makesure to click on “Apply” or “OK” to save your changes, and then runyour game. You will now be able to resize your game window. Note that bydefault the aspect ratio of the game will remain the same no matterwhat the size of the window is, which is also something that you canchange through the Game Options for your platform.
View Scrolling
Youcan jump on the windows now, but you can’t go past the top boundary ofthe room. Since this will be an infinite scroller, we want the player tobe able to climb as high as they can!
Toachieve that effect, we’re going to move our instances down to give theillusion that the player is moving up. We’ll do this when the playerreaches the middle of the screen:
Wewill need to move instances of multiple objects down to give theillusion of the player moving up. Right now we only have windows, butlater we will add civilians, fires, and other objects, which will allneed to be moved down as the player goes up. This means that we somehow needto group these objects together…
Object Parenting
GameMakerhas a solution for this called “object parenting”. Basically, you cancreate a “parent” object and assign some objects as its “children”. Anychanges you make to the parent object will also be applied to itschildren!
Wecan use this concept to create a parent object for those objects thatneed to be moved down. Go into the Objects group in your Asset Browserand create a new object called “obj_move_parent”. We don’t need toassign a sprite to this object as it won’t appear anywhere -- it existsonly in the game assets so we can access its children.
Nowto add children to this object, go into its Object Editor and click on the “Parent” button. This will open a new window where you can assign a parent to thisobject, however we want to add a child to it -- so click on the plus button to the right of the “Children” section and select obj_window (alternatively you can simply drag in that object from the Asset Browserand drop it into the “Children” section).
Rightnow this is the only child that this object has, but when we add moreobjects later we can simply add them as children to this object and theywill automatically move down too.
Now let’s continue with our goal to implement scrolling.
Conditions
Gointo obj_player’s Events window and click on “Add Event”. Under “Step”,you will see three events, and you need to select the one that simplysays “Step”. It will be added to your object.
Thisevent runs every frame, so the actions you add here will constantly runfor the instance. Actions in this event run unconditionally, but we want to add our own conditions to them: to check if theplayer is jumping up, and to check if it’s in the upper half of thescreen.
Forthat purpose we have the “If Variable” action, which checks whether avariable meets a certain condition. Then we can connect actions to thataction so that they run when the condition is met.
A variable keeps track of a value. For example, xand yare variables that hold the instance’s X and Y coordinates respectively. Similarly, hspeedand vspeedhold the horizontal and vertical speeds of the instance, respectively.
Asyou can see in the image above, this action acts as a condition (to check if avariable is holding a certain value). When that condition is met, anyactions connected to it on the right are executed. This means that ifthat condition is not met, then those actions simply won’t run.
Scrolling
To scroll the view, we want to do a few things:
- Get the player’s upward speed ⬆
- Turn that around so it becomes a downward speed ⬇
- Apply that downward speed to the window so it moves down.
Itsounds simple, but we also need to apply a condition to these actions.That condition will check if the player is moving up, because we onlywant the room to scroll when the player is jumping, not falling.
In the Step event's Toolbox, search for the “If Variable” action and drop it into the event. The variable that we need to check is vspeed(the player’s vertical speed) so enter that into the “Variable” field.
The“Is” option will be at “Equal” by default. This lets us check whetherthe variable’s value is equal to some other value (for example, checkingif it’s equal to 4, or 200, and so on), but we want to check if vspeedisless than 0. If you remember, we set the instance’s vertical speed to-35 to make it jump up. This means that if the player is still jumping,its vertical speed would be negative, so we need to check ifit’s less than 0.
Change the “Is” field to “Less”, and in the “Value” field enter 0 (zero). Now our condition checks if vspeedis less than 0!
Note: The "Not" option is used to flip the condition, making it false when it would be true and vice-versa. We don't need to use it right now.
Nowwe’re going to attach some actions to the “If Variable” action, so thatthey run when the condition is true. As previously mentioned, we needto get the player’s upward speed and turn it around. In the Toolbox,search for “Declare Temp” and add that action to the event: make sure toattach it to the right of the “If Variable” action!
Note: If you place an action below the “If Variable” action, it will not be controlled by that condition and will be independent.
Usingthis action we can declare (or create) a “temporary variable”. Such avariable only exists for the current event and is not available afterthat.
Wewant to create a temporary variable to store the downward speed. In the“Name” field, enter downspeed which will be our variable’s name (youcan name it whatever you like). In the “Value” field, enter -vspeed (negative vspeed).
vspeedstores the player’s vertical speed, and since it’s jumping up (we made that sure in our condition), vspeedwillbe negative. To turn this speed around we use the negative sign, andsince this value is already negative, it will result in a positivenumber. That number will be saved into our downspeedvariable.
Nowwe want to apply this downward speed to the window, so it moves down.You might remember that we created an object called obj_move_parent togroup those objects that need to move down. We’re going to apply ourdownward movement to that parent object, so that it’s automaticallyapplied to all of its children.
Inthe Toolbox, search for “Set Instance Variable” and drop it into thesame chain that was started by our “If Variable” action, so that it’salso controlled by that condition.
Beforewe modify any of this action’s properties, we need to think about whatit will do. We want to use this action to move the windows, however weare inside the player object, so it will move the player. To apply thisaction to obj_move_parent instead, click on the little arrow tothe right of the action’s name, which will open the Asset Explorer.
Thiswindow will allow you to select an object to which this action willapply. Since we want to move any objects assigned to obj_move_parent, gointo the Objects group and click on obj_move_parent (or just enter thatinto the “Expression” field). You will notice that your action now has apink border, indicating that it will be applied to another instance.
Now set the “Variable” field to “Y Coordinate” and the “Value” field to downspeed.Make sure that the “Relative” checkbox is enabled. This will move theinstance (relative to its own position) on the Y axis, by the amountstored in the downspeedvariable. In short, the windows will now move down! This is what our Step event should look like at this point:
If you run the game now, you will see the windows move down, however they don't wait for the player to get to the middle of the screen first...
Upper Half Only!
Theissue right now is that the view is always moving up, but it shouldonly move if the player touches the upper half of the room.
Toachieve this we’re going to use another condition. In the player’s Stepevent, add a new “If Variable” action at the top. We want to use this action tocheck whether the player is in the upper half of the room.
We can get the size of our room by reading the room_widthvariable for its width, and the room_heightvariable for its height. For our condition, we’re going to check if the player’s y(itsY position) is less than room_height / 2, as that gives us half theroom’s height. So in the new “If Variable” action, set:
- “Variable” to y
- “Is” to “Less”
- “Value” to room_height / 2
Nowwe want to apply the rest of our actions to this action, so they only run when this condition is met. Drag the old “If Variable” action anddrop it to the right of our new action, so that it controls all of ourprevious actions.
Ifall of this has happened -- the player reached the upper half of theroom while jumping -- we also want the player to stick to the center ofthe room, as we’re moving the rest of the objects in relation to theplayer.
Inthe same chain as our previous actions (controlled by the twoconditions) we’re going to add a new “Set Instance Variable” action.This will set the player’s Y position to the center of the room, so thatit doesn’t move any further into its upper half. To achieve that, we’llset “Variable” to “Y Coordinate” and “Value” to room_height / 2.
When you run the game, you will see that the view only scrolls when the player intersects the upper half of the screen:
Woohoo!
Background Scrolling
You will notice that the background wall doesn't scroll. We'll need a different approach to make that work, as it's a background layer and not an object instance.
Let’sgo back into the player’s Step event. In the Toolbox, search for the“Function Call” action and drag and drop it into the event, below the“Set Instance Variable” action.
Thisaction lets us run a “function”, which is simply an extra action for usto use. We want to get the current Y position of the background layer,so in the “Function” field, enter layer_get_y. In the “Argument” field, enter “Background” -- this is the name of our background layer. In the “Target” field, enter back_yand enable the “Temp” checkbox.
Note: An “argument” is simply an option for a function. Functions can take multiple arguments.
Thisaction will get the Y position of the background layer and store it in anew, temporary variable called back_y. We’ll use this variable ina new action to move the layer, so in the Toolbox, search for the“Function Call” action again (or find it under “Recently Used”) and drop it below your previous “Function Call” action.
We want to use this new “Function Call” action to change the Y position of our background layer. In the “Name” field, enter layer_y, andin the “Argument” field, enter “Background” (same as the previousaction). This function needs a second argument, so click on the plus button to the left of the action, which will add another argumentfield. Set this to back_y + downspeed.
Now when you run the game you will see that the background moves as well:
It definitely looks like the player is going up, when in reality it's the other visuals that are going down!
Spawning Windows
Youcan go as high as you want now, but there aren’t any more windowsbeyond the ones you placed in the room. We want the windows to keepcoming in so the player can climb as high as they can!
We’renot going to create new window instances as the view scrolls. Instead,when a window exits the room from the bottom, we want it to reappear atthe top at a different horizontal position.
Toimplement this, let’s go into the window object (obj_window) and addthe Step event. We’ll use this event to check if the window has gone outof the room and if it has, we’ll respawn it. To check that we need anew condition -- so add an “If Variable” action and let’s proceed.
Condition: Below Room?
We want to check if the Y position of the instance is greater than room_height,which is the total height of the room. If this condition is met itmeans that the instance is below the room. However, we need to becareful with this, as the Y position of the instance refers to itsorigin, and we placed the origin of our window sprite above its sill.This means that such a condition will only check if that origin point isbelow the room -- not the whole window!
We can work around this by adding an offset to the room’s height in the condition. So instead of checking if the yis greater than room_height, we’ll check if it’s greater than room_height + 360as that gives us the extra room we need for the whole window to disappear.
In the "If Variable" action, set the “Variable” field to y, the “Is” field to “Greater” and the “Value” field to room_height + 360. This condition will allow us to perform actions when the window is below the room.
Thefirst thing we want to do now is to calculate a random X coordinatewhere the window will be placed, so it’s not always in the exact samehorizontal position. For that we’re going to use the “Get Random Number”action -- find it in the Toolbox and attach it to the “If Variable”action.
Thisaction generates a random number based on our specified range. First ofall, make sure that the “Type” is set to “Integer” since we don’t want adecimal value. We want the new X position to be anywhere between 0 androom_width (as that is the room’s range on the X axis), but there issomething else to consider.
Wedon’t want the window to spawn too near to the left or right border, asthen the window will be cut off and will not appear in full. We’regoing to allow a margin of 200 pixels for the spawning range, so we’ll set the“Minimum” field to 200and the “Maximum” field to room_width - 200.
Thiswill now generate an integer value between that range, but how do weretrieve it? For that we’re going to use the “Target” field. Simplyenter a variable name here and the generated value will be stored intothat variable.
Wewant to use a temporary variable to store the random value, as we onlyneed it for this event. Set the “Target” field to new_x and enable the “Temp” checkbox.
Nowto respawn the window above the room (so it can come down again) weneed to change its position. Find the “Jump To Point” action in theToolbox and drag it into the chain. This action allows us to set new Xand Y coordinates for the instance, making it instantly jump to that point. For the “X” field we’re going to use the new_xvariablewhich is randomly generated. For the “Y” field, we’ll use -200(negative 200) to place it above the room and give it a 200-pixelmargin.
Your event should look like this now:
If you run the game now, you will see that the windows are being randomly generated!
Tip: If you need help with your project at any point, you can join the GameMaker Communityand create a thread there.
Ifyou’re not able to reach any newly spawned windows because they spawn toohigh, or if some windows spawn too close to each other, you will need to adjust the separation between your windows in the RoomEditor. You can also place extra windows above the room to fill any gaps:
Combo Jump Issue
There is an issue with our game right now. If there is a row of windows, you will see that the player easily boosts through it:
Thisis not intended, as we want the player to bounce on each windowindividually. We’re facing this issue because the player jumps as soonas it comes in contact with a window, even as it’s jumping! We only wantit to be able to jump while it’s falling.
Tofix this problem, let’s go into the player object (obj_player) and openits Collision event with obj_window. Here we have an action that setsthe player’s vertical speed to -35, making it jump. We want to put this action under a condition to check if the player is falling, so search forthe “If Variable” action in the Toolbox and drag it into the event.
Movingdown involves a positive vertical speed, so to check if the player isfalling, we need to check if its vertical speed is greater than 0. So inthe “If Variable” action, set the “Variable” field to vspeed,the “Is” field to “Greater” and the “Value” field to 0. This will nowcheck if the player is falling, and to make it jump only when thiscondition is met, drag the “Set Speed” action and attach it to the “IfVariable” action.
You will now see that the issue is fixed. With that done, let’s move on to the final part of this tutorial!
Street Area
Ourgame only has a brick background at the moment. We want to make it soyou can see the street in the beginning, adding polish to our game.
Inthe Sprites group in your Asset Browser, create a new sprite called“spr_street”. Import the image with the same name from the tutorialassets.
Inthe Objects group, create an object for this called “obj_street” and assign the spr_street sprite to it. Openits “Parent” menu and click where it says “No Object”. This will open upthe Asset Explorer where you can select an object to assign as thisobject’s parent. We want this street object to automatically move downwith the view, so we’re going to set obj_move_parent as its parent.
Thefinal step is to place it in the room. Open the rm_game room, make surethe “Instances” layer is selected (which is below the “Player” layer)and drag obj_street into the room area to create an instance. Place itat the bottom and make sure it doesn’t overlap with any windows (if they do, move the windows up).
Inthe game you will now see the street area in the beginning, which willsimply move down with the view just like our windows. We didn’t have toadd any more actions to make it move, because we're already applying downward movement to obj_move_parent, which is the parent of thewindow object and the street object.
Summary
Before we continue to the next part of the tutorial, let’s summarize what we have learned so far:
- You can import images as sprites, and create objects that can be programmed
- Room layers can be organized so you can control which instances appear at the top
- Input Events can be used for player control
- Object Parenting can be used to group multiple objects together and move them at once
- Finally: You are awesome at making games!
In the next part, we’re going to add civilians that can be rescued and the ability to score points.
Next:Fire Jump Tutorial - Part 2