๐ฏ My First GameMaker Game ยท Episode 2 of 5 ยท See All Episodes
๐ Episode 2 ยท Beginner+ ยท The GameMaker Classic
Run & Jump! GML Platformer
THE GameMaker genre: pixel-perfect platforming with place_meeting collision, gravity, coyote-time jumping, tile-decorated rooms and a camera that follows, the exact recipe behind countless indie hits.
Solid level pieces are instances of obj_. The sprite is set to Middle Centre so position maths stays simple. Room grid snapping was set to .
๐ง
Knowledge Check
+15 XP
Why do we use OUR OWN hsp/vsp instead of the built-in hspeed/vspeed here?
AThe built-ins are broken
BWe need to test collisions BEFORE applying movement, manual variables give us that control
CThey are faster to type
2
๐ถ
place_meeting Movement
The most famous 10 lines in GameMaker
Locked
๐ฏ
Goal for this step
Implement collision-safe horizontal and vertical movement.
1place_meeting(x, y, obj) asks: "if I stood at this position, would I overlap that object?", collision BEFORE moving. This is GameMakerโs crown jewel.
2The pattern: compute hsp from input; if the spot ahead is blocked, inch up to the wall pixel-by-pixel then zero the speed; else move.
3Same for vertical with gravity added to vsp first.
4This exact Step code is in thousands of shipped games. Learn it by heart.
obj_player ยท Step
var key_left = keyboard_check(vk_left);
var key_right = keyboard_check(vk_right);
hsp = (key_right - key_left) * move_speed;
vsp += grav;
// horizontal
if (place_meeting(x + hsp, y, obj_wall)) {
while (!place_meeting(x + sign(hsp), y, obj_wall)) x += sign(hsp);
hsp = 0;
}
x += hsp;
// vertical
if (place_meeting(x, y + vsp, obj_wall)) {
while (!place_meeting(x, y + sign(vsp), obj_wall)) y += sign(vsp);
vsp = 0;
}
y += vsp;
โจ๏ธ
Code Challenge
+20 XP
Complete the pixel-perfect horizontal block:
obj_player ยท Step
if ((x + hsp, y, obj_wall)) {
while (!place_meeting(x + (hsp), y, obj_wall)) x += sign(hsp);
hsp = ;
}
๐ก Hint: The look-ahead test; then creep one pixel at a time in the movement direction until flush; then stop.
๐ง
Knowledge Check
+15 XP
The while-loop that inches toward the wall gives youโฆ
ASlower movement
BPixel-perfect landing flush against walls, no gaps, no overlaps, at any speed
CWall destruction
3
๐ฆ
Jumping & Coyote Time
Grounded checks plus the forgiveness timer
Locked
๐ฏ
Goal for this step
Add jumping with the pro-level coyote-time polish.
1Grounded test: place_meeting(x, y + 1, obj_wall), is there floor one pixel below?
2Track coyote frames: reset to 6 when grounded, count down in air; jump allowed while > 0.
3(6 frames = 0.1 s at 60 fps, the same window you built in C++. Same design, new engine.)
4Also add jump buffering: remember a jump press for 6 frames so pressing JUST before landing still jumps. The two timers together = jumps that feel psychic.
obj_player ยท Step (additions)
var on_ground = place_meeting(x, y + 1, obj_wall);
if (on_ground) coyote = 6; else coyote--;
if (keyboard_check_pressed(vk_space)) buffer = 6; else buffer--;
if (buffer > 0 && coyote > 0) {
vsp = jump_force;
coyote = 0;
buffer = 0;
}
โ๏ธ
Fill in the Blanks
+15 XP
The grounded check looks one pixel the player. Coyote time forgives late jumps; jump forgives early ones. Both timers run about frames.
๐ง
Knowledge Check
+15 XP
Jump buffering handles the case where the player presses jumpโฆ
ATwice quickly
BSlightly BEFORE landing, the press is remembered and fires on touchdown instead of being eaten
CWhile paused
4
๐ฅ
Camera & A Bigger World
Viewports that follow the player smoothly
Locked
๐ฏ
Goal for this step
Expand the room and set up a smooth-follow camera.
1Resize the room to 2400ร500 and build a longer level.
2Room editor โ Viewports: enable Viewport 0, camera 800ร500.
3Smooth-follow beats hard-lock: lerp the camera toward the player each Step in obj_game.
4lerp(a, b, 0.1) moves a tenth of the way per frame, smooth chase, no snapping. Clamp inside the room.
obj_game ยท Step
var cam = view_camera[0];
var cx = camera_get_view_x(cam);
var target = clamp(obj_player.x - 400, 0, room_width - 800);
camera_set_view_pos(cam, lerp(cx, target, 0.1),
camera_get_view_y(cam));