This tutorial will teach you how to make an animated platformer. This tutorial was written using Game Maker 7.
This tutorial was made by
spacechase0.
There may be an easier way to do this, but this is how I do it.
Note to the reader
This tutorial assumes that you have the following objects/sprites with certain names:
| Player Object | obj_player |
| Player Idle Right Sprite | spr_player_idle_right |
| Player Idle Left Sprite | spr_player_idle_left |
| Player Walking Right Sprite | spr_player_walk_right |
| Player Walking Left Sprite | spr_player_walk_left |
| Player Jump Right Sprite | spr_player_jump_right |
| Player Jump Left Sprite | spr_player_jump_left |
| Player Fall Right Sprite | spr_player_fall_right |
| Player Fall Left Sprite | spr_player_fall_left |
| Player Crouch Right Sprite | spr_player_crouch_right |
| Player Crouch Left Sprite | spr_player_crouch_left |
| Player Ladder Sprite | spr_player_ladder |
| Player Mask Sprite | spr_player_mask |
| Player Crouch Mask Sprite | spr_player_crouch_mask |
| Block Object | obj_block |
| Block Sprite | spr_block |
| Ladder Object | obj_ladder |
| Ladder Sprite | spr_ladder |
| Draw Object | obj_draw |
| Coin Object | obj_coin |
| Coin Sprite | spr_coin |
| Enemy Object | obj_enemy |
| Enemy Right Sprite | spr_enemy_right |
| Enemy Left Sprite | spr_enemy_left |
Player Object
Create Event
In the Create Event of the player, set the following variables:
face = 2
jump = 1
move = 1
fall = 1
crouch = 1
ladder = 1
If you don't want some of the variables, then take them out. Just be sure to take out bits of code later that might use those variables. If you don't you will get an error. Examples on how to remove some of the variables will be listed later.
This code will put the facing variable (which direction you are facing, 1 = left 2 = right), jumping variable (going up, 1 = no 2 = yes), moving variable (whether you are moving or not, 1 = no 2 = yes), falling variable (going down, 1 = no 2 = yes), crouching variable (crouching check, 1 = no 2 = yes), and ladder variable (on a ladder check, 1 = no 2 = yes). You can use false for 1 and true for 2, but make sure that if you change a variable you have to remember to make it check true/false and not 1 and 2.
Please note that these are just interpretations of it, 1 doesn't really mean no or left and 2 doesn't really mean yes or right.
Step Event
This section contains the code you will need to put in the Step Event.
Gravity
Gravity can be pretty easy to make, especially if you know what you are doing. In the Step Event of the player, put the following code:
if place_free(x,y+1) and distance_to_object(obj_ladder) >= 1
{
gravity = 0.45
ladder = 1
}
if !place_free(x,y+1) and distance_to_object(obj_ladder) >= 1
{
gravity = 0
jump = 1
fall = 1
ladder = 1
}
if distance_to_object(obj_ladder) <= 0
{
gravity = 0
jump = 1
fall = 1
ladder = 2
vspeed = 0
}
gravity_direction = 270
if vspeed > 9.5
{vspeed = 9.5}
if vspeed > 0
{fall = 2 jump = 1}
if vspeed < 0
{fall = 1 jump = 2}
if vspeed = 0
{fall = 1 jump = 1}
Now, lets take a look at the code and disect it. If you are learning GML, this might help you.
if place_free(x,y+1) and distance_to_object(obj_ladder) >= 1
{
gravity = 0.45
ladder = 1
}
This code checks if the player is in the air (place_free(x,y+1)) and if you are not at the ladder object (distance_to_object(obj_ladder) >= 1). Then, in brackets, it tells the program what to do if you are in the air. It tells the player to have gravity almost half of one (gravity = 0.45) and it sets the ladder variable to 1, meaning you are not on a ladder.
if !place_free(x,y+1) and distance_to_object(obj_ladder) >= 1
{
gravity = 0
jump = 1
fall = 1
ladder = 1
}
This line of code is almost exactly like the previous, but they are both important. This line checks if you are not on the ground (the ! is not). Also, it checks if you are not on a ladder, as before. If both are true, then several things will happen. First, it will turn the gravity off. It will also change the jumping and falling variables to 1, which means you are not jumping or falling. It also set the ladder variable to 2, for purposes seen later.
if distance_to_object(obj_ladder) <= 0
{
gravity = 0
jump = 1
fall = 1
ladder = 2
vspeed = 0
}
This line of code is a little different from the other two. This one checks if you are on the ladder, and then it turns the gravity off, sets the jump/fall variables to 1, sets the vspeed to 0 (incase you fell onto or jumped onto the ladder), and sets the ladder variable to 2. This will be used later in the step event.
gravity_direction = 270
This makees sure the every step the gravity is going down. Remember, if you are changing the gravity direction, 0 degrees is right, and it goes counter-clockwise up to 360.
if vspeed > 10
{vspeed = 10}
This makes sure that the vspeed does not go higher than 10. This is so that gravity does not pull too hard on the player. Players can go through objects if the gravity is high enough.
if vspeed > 0
{fall = 2 jump = 1}
This sets the jump/fall variables, used for later.
if vspeed < 0
{fall = 1 jump = 2}
This sets the jump/fall variables, used for later.
if vspeed = 0
{fall = 1 jump = 1}
This sets the jump/fall variables, used for later.
Movement, Sprites, Etc.
Time for more code! This section will also explain each line.
if keyboard_check(vk_left) and place_free(x-5,y)
{
x-=5
move = 2
face = 1
}
if keyboard_check(vk_right) and place_free(x+5,y)
{
x+=5
move = 2
face = 2
}
if keyboard_check_pressed(vk_up) and !place_free(x,y+1) and ladder = 1
{vspeed = -9}
if keyboard_check(vk_up) and ladder = 2
{
y -= 3
image_speed = 0.33
}
if keyboard_check(vk_down) and move = 1 and ladder = 1
{
crouch = 2}
if keyboard_check(vk_down) and ladder = 2
{
y += 3
image_speed = 0.33
}
if !keyboard_check(vk_down) and !keyboard_check(vk_up) and ladder = 2
{image_speed = 0}
if !keyboard_check(vk_left) and !keyboard_check(vk_right)
{move = 1}
if keyboard_check(vk_left) and keyboard_check(vk_right)
{move = 1}
if !keyboard_check(vk_down)
{crouch = 1}
You can use this for all of the controls. If you don't understand this, then you should keep reading.
if keyboard_check(vk_left) and place_free(x-5,y)
{
x-=5
move = 2
face = 1
}
This code is very different then the one in the gravity section. It checks if you are holding left (keyboard_check(vk_left)) and if the place 5 pixels to the left is empty. If it is, then it moves the player to the plae 5 pixels to the left, sets the moving variable at 2, and the face variable to 1.
if keyboard_check(vk_right) and place_free(x+5,y)
{
x+=5
move = 2
face = 2
}
This is almost the same as the last line, but it is not. It checks if your are pressing right instead of left, and checks/moves you to 5 pixels to the right instead of 5 pixels to the left. Another difference is that it sets face at 2 instead of 1. The only thing that is the same is that it sets move at 2.
if keyboard_check_pressed(vk_up) and !place_free(x,y+1) and ladder = 1 {vspeed = -9}
Jumping is fairly simple on platformers. This check if you have pressed up, and when you do, if you are on solid ground and not on a ladder. Then it sets the vspeed to -9, which is up. This pretty much makes you go up against gravity. The gravity will slowly make the vspeed higher (higher because jumping sets it to a negative).
if keyboard_check(vk_down) and move = 1 and ladder = 1
{crouch = 2}
This checks if you are holding down and if you are not moving and not on a ladder. If so, it sets the crouching variable, which is used later on.
if keyboard_check(vk_down) and ladder = 2
{
y += 3
image_speed = 1
}
Another bit of code, another explanation. What this does is if you are holding the down arrow key and you are on a ladder then it makes you move down a little bit on the ladder. Don't worry, all of the sprite and mask handling will be done at the end of the step event. The image_speed is for if the arms/legs/etc. are moving as if you are actually climbing. See explanation for the code below for more info.
if !keyboard_check(vk_down) and !keyboard_check(vk_up) and ladder = 2
{image_speed = 0}
This bit of code is very important, unless you have ladder climbing sprite that doesn't have moving body parts. Pretty much it makes it where the character doesn't move when you aren't going up and down, useful if the arms and legs move up and down as if you were really climbing.
if !keyboard_check(vk_left) and !keyboard_check(vk_right)
{move = 1}
This is used for when you stop moving, it sets move to 1 so that sprite handling will be accurate for later on in the Step Event.
if keyboard_check(vk_left) and keyboard_check(vk_right)
{move = 1}
This is a debug for the moving. This makes it where you don't have a walking animation when you are holding left and then also start holding right or vice versa.
if !keyboard_check(vk_down)
{crouch = 1}
If you are not holding the down arrow key, it sets crouch to 1.
Sprite and Mask Handling
Time to start using those variables! Here is the code for this section:
if move = 1 and face = 1 and jump = 1 and fall = 1 and ladder = 1
{
sprite_index = spr_player_idle_left
image_speed = 1
mask_index = spr_player_mask
}
if move = 1 and face = 2 and jump = 1 and fall = 1 and ladder = 1
{
sprite_index = spr_player_idle_right
image_speed = 1
mask_index = spr_player_mask
}
if move = 2 and face = 1 and jump = 1 and fall = 1 and ladder = 1
{
sprite_index = spr_player_walk_left
image_speed = 1
mask_index = spr_player_mask
}
if move = 2 and face = 2 and jump = 1 and fall = 1 and ladder = 1
{
sprite_index = spr_player_walk_right
image_speed = 1
mask_index = spr_player_mask
}
if jump = 2 and fall = 1 and face = 1 and ladder = 1
{
sprite_index = spr_player_jump_left
image_speed = 1
mask_index = spr_player_mask
}
if jump = 2 and fall = 1 and face = 2 and ladder = 1
{
sprite_index = spr_player_jump_right
image_speed = 1
mask_index = spr_player_mask
}
if fall = 2 and jump = 1 and face = 1 and ladder = 1
{
sprite_index = spr_player_fall_left
image_speed = 1
mask_index = spr_player_mask
}
if fall = 2 and jump = 1 and face = 2 and ladder = 1
{
sprite_index = spr_player_fall_right
image_speed = 1
mask_index = spr_player_mask
}
if crouch = 2 and move = 1 and face = 1 and jump = 1 and fall = 1 and ladder = 1
{
sprite_index = spr_player_crouch_left
image_speed = 1
mask_index = spr_player_crouch_mask
}
if crouch = 2 and move = 1 and face = 2 and jump = 1 and fall = 1 and ladder = 1
{
sprite_index = spr_player_crouch_right
image_speed = 1
mask_index = spr_player_crouch_mask
}
if ladder = 2
{sprite_index = spr_player_ladder}
Explanations anyone? Here is one for each line. All of the image_speed settings are used for debug purposes, and the mask stuff is for masking sure the collision checking is right.
if move = 1 and face = 1 and jump = 1 and fall = 1 and ladder = 1
{
sprite_index = spr_player_idle_left
image_speed = 1
}
If you are not moving, facing left, not jumping and, not falling, and not on a ladder then it will set the sprite to the spr_player_idle_left.
if move = 1 and face = 2 and jump = 1 and fall = 1 and ladder = 1
{
sprite_index = spr_player_idle_right
image_speed = 1
}
This is the same as the previous bit, except it is when you stopped facing right it sets it to spr_player_idle_right.
if move = 2 and face = 1 and jump = 1 and fall = 1 and ladder = 1
{
sprite_index = spr_player_walk_left
image_speed = 1
}
If you are walking to the left on the ground and not on a ladder, then this will put the walking left animation.
if move = 2 and face = 2 and jump = 1 and fall = 1 and ladder = 1
{
sprite_index = spr_player_walk_right
image_speed = 1
}
Walking right will trigger this code. It puts the animation to the correct sprite.
if jump = 2 and fall = 1 and face = 1 and ladder = 1
{
sprite_index = spr_player_jump_left
image_speed = 1
}
When you jump and are facing left, then the player will get this sprite.
if jump = 2 and fall = 1 and face = 2 and ladder = 1
{
sprite_index = spr_player_jump_right
image_speed = 1
}
Jumping right will make you get the sprite spr_player_jump_right.
if fall = 2 and jump = 1 and face = 1 and ladder = 1
{
sprite_index = spr_player_fall_left
image_speed = 1
}
Did you just jump off a cloud on the left side? Well this piece of code will put the proper animation.
if fall = 2 and jump = 1 and face = 2 and ladder = 1
{
sprite_index = spr_player_fall_right
image_speed = 1
}
When you play the first level of Mario, there is usually a bunch of stairs to jump onto to get to the top of the flag. What happens when you miss the flag? You go into the spr_player_fall_right sprite.
if crouch = 2 and move = 1 and face = 1 and jump = 1 and fall = 1 and ladder = 1
{
sprite_index = spr_player_crouch_left
image_speed = 1
}
What happens if something is flying towards you? You need to crouch! If you are were going left when you crouched, then this bit of code is sure to save you!
if crouch = 2 and move = 1 and face = 2 and jump = 1 and fall = 1 and ladder = 1
{
sprite_index = spr_player_crouch_right
image_speed = 1
}
Did you accidently poke a beehive on a platformer? If this code is in your step event and you are running to the right, then you can crouch correctly.
if ladder = 2
{sprite_index = spr_player_ladder}
This will make the player's sprite change into spr_player_ladder.
Other changes to obj_player
Do NOT make the player solid because it might mess up the ladder. In the collision event with obj_block, put
if vspeed > 0 and !place_free(x,y+vspeed)
{move_contact(270)}
vspeed = 0
This code is very important! It keeps you from falling through the block.
Be sure to give the player one of the idle sprites before you start the game or else the player will be invisible. Also, give the player a mask of the sprite spr_player_mask.
Changes to other objects
Give obj_block the spr_block as a sprite. Make it solid
Also, make obj_ladder non-solid, and give it spr_ladder as a sprite.
Collectables
Create a sprite name spr_coin and an object called obj_coin with spr_coin as a sprite. Be sure it is not solid. Also, make an object called obj_draw and make it persistent. Be sure it is not solid and do not give it a sprite. All of the code needed to put in the player's collision object with the collectable is:
global.points += 1
with (other)
{instance_destroy()}
Put this in the create event of obj_draw:
global.points = 0
And put this in the Draw event of obj_draw
draw_text(8,8,global.points)
Keep reading for an explanation of the code.
global.points += 1
This adds one point to the variable when the player grabs the coin.
with (other)
{instance_destroy()}
Whenever other is in a collision event, it means the instance of the object you just touched. Using other instead of obj_coin will make sure that only the coin you just grabbed gets deleted. The with means that whatever is in the brackets (in this case instance_destroy()) will happen to the object in the parenthesis.
global.points = 0
This is in the game start event of obj_draw. This will make it where you can use global.points.
draw_text(8,8,'Points: '+string(global.points))
This line of code will draw how many points you have near the top leaft corner of the course.
Now just place obj_draw in the first room and place the obj_coin where you want it.
Enemies
Now you will be able to make a simple enemy that goes left and right.
dir = choose(2,-2)
This goes in the create event. Basically, this will just pick a direction to go when the enemy is created.
if place_free(x,y+1)
{
gravity = 0.45
}
else
{
gravity = 0
}
gravity_direction = 270
if vspeed > 9.5
{vspeed = 9.5}
if place_free(x+dir,y)
{
x += dir
}
else
{
dir = -dir
}
if place_meeting(x+dir,y,obj_player) or place_meeting(x-dir,y,obj_player) and !(place_meeting(x,y+1,obj_player))
{
with (obj_player)
{
instance_destroy();
}
}
else if place_meeting(x,y+1,obj_player)
{
with (obj_player)
{
vspeed = -4
}
instance_destroy()
}
if dir > 0
{
sprite_index = spr_enemy_right
}
else
{
sprite_index = spr_enemy_left
}
Put this in the step event. The beginning part is an edited version of the gravity code earlier, so we won't talk about it.
if place_free(x+dir,y)
{
x += dir
}
else
{
dir = -dir
}
This just makes the enemy go in the current direction if the place is free, and otherwise he turns around.
if place_meeting(x+dir,y,obj_player) or place_meeting(x-dir,y,obj_player) and !(place_meeting(x,y+1,obj_player))
{
with (obj_player)
{
instance_destroy();
}
}
else if place_meeting(x,y+1,obj_player)
{
with (obj_player)
{
vspeed = -4
}
instance_destroy()
}
This fancy part of the script is necessary. If you run into the side of the enemy, but are not on top of him, he will destroy you. But if you jump on him, he will die.
if dir > 0
{
sprite_index = spr_enemy_right
}
else
{
sprite_index = spr_enemy_left
}
This last part is nothing fancy, it just makes the enemy show the right direction.
Coming soon
- Enemies (like a goomba)
- Temporary invincibility (like a star)
- Trail effect
- Slope movement
- Lava/Killing Blocks
- Kirby-Style Jumping
- Example!
Backlinks
These pages link back to this page.
Side Notes
Please note that this is the last thing I will do with game maker. I have moved on to C++, and I will try to finish this, but other than that I probably won't be here very much.