HT Games

Creating a Mario-Style Platformer in GameMaker Studio 2 (Complete Tutorial Outline)

Building a Mario-like platformer in GameMaker Studio 2 (GMS2.3+/GML Visual or Code) is a classic learning project. Here's a structured roadmap.

1. Project Setup

  • New Project: GML Code (recommended) or GML Visual.
  • Resolution: 640×360 (16:9, scales to 720p/1080p/4K). Viewport = 640×360.
  • Physics: Don't use built-in Physics Engine for platformers. Write custom collision (see below).

2. Asset Pipeline

  • Sprites: Import sprite strips (Idle, Run, Jump, Fall, Climb, Swim, Power-ups). Set Origin: Middle Center (feet).
  • Tilesets: 16×16 or 32×32. Collision layer = "Solid" tile layer.
  • Audio: .ogg/.wav. Group: Music, SFX, Voice.

3. Player Object (obj_player)

// Create Event
hsp = 0; vsp = 0; grav = 0.45; jump_force = -9.5; max_speed = 4.5; accel = 0.35; decel = 0.4; coyote_time = 6; jump_buffer = 6; // frames
coyote = 0; jbuf = 0; on_ground = false; state = "idle"; // idle, run, jump, fall, attack
sprite_index = spr_mario_idle; image_speed = 0.15;

// Step Event
// Input
var left = keyboard_check(vk_left) or keyboard_check(ord("A"));
var right = keyboard_check(vk_right) or keyboard_check(ord("D"));
var jump_pressed = keyboard_check_pressed(vk_space) or keyboard_check_pressed(ord("W"));
var jump_held = keyboard_check(vk_space) or keyboard_check(ord("W"));

// Jump Buffer
if (jump_pressed) jbuf = jump_buffer; else if (jbuf > 0) jbuf--;

// Horizontal
if (left) hsp = max(hsp - accel, -max_speed);
else if (right) hsp = min(hsp + accel, max_speed);
else hsp = lerp(hsp, 0, decel);

// Coyote Time
if (on_ground) coyote = coyote_time; else if (coyote > 0) coyote--;

// Jump Logic
if (jbuf > 0 && coyote > 0) {
    vsp = jump_force;
    on_ground = false;
    coyote = 0;
    jbuf = 0;
    audio_play_sound(snd_jump, 10, false);
}

// Variable Jump Height (cut)
if (!jump_held && vsp < -2) vsp = -2;

// Gravity
vsp = min(vsp + grav, 16); // terminal velocity

// Collision & Move (see Section 4)
// ... collision code sets on_ground, adjusts x/y ...

// Animation State Machine
if (!on_ground) {
    if (vsp < 0) state = "jump"; else state = "fall";
} else if (hsp != 0) state = "run";
else state = "idle";
sprite_index = sprite_get("spr_mario_" + state);

4. Precise Collision (The Mario Feel)

// Horizontal
var _x = x + sign(hsp);
repeat(abs(hsp)) {
    if (!place_meeting(_x, y, obj_solid)) x = _x;
    else { hsp = 0; break; }
    _x += sign(hsp);
}

// Vertical
var _y = y + sign(vsp);
repeat(abs(vsp)) {
    if (!place_meeting(x, _y, obj_solid)) y = _y;
    else {
        vsp = 0;
        if (vsp > 0) on_ground = true; else on_ground = false; // head bonk
        break;
    }
    _y += sign(vsp);
}

This pixel-perfect loop prevents sticking, allows sub-pixel precision, and feels tight.

5. Enemies (Goomba / Koopa)

  • State machine: Walk → Stomped (flattened) → Kicked (shell) → Shell slide.
  • Shell: obj_shell with high hsp, kills enemies, breaks bricks, hurts player.
  • Stomp detection: if (vsp > 0 && place_meeting(x, y+1, obj_enemy)) → bounce (vsp = jump_force * 0.6).

6. Power-Ups & Blocks

  • ? Block: Timer → spawn Mushroom / Flower / Star / Coin. Hit from below (vsp < 0 && place_meeting(x, y-1, obj_question)).
  • Mushroom: Moves right, falls, turns at walls. Collision → player.state = "grow" (animation → sprite_index = spr_mario_big, bbox height ×2).
  • Flower: Shoot fireballs (obj_fireball: linear, bounces, dies on wall).
  • Star: Invincibility timer, palette cycle, kill-on-touch.

7. Camera

// obj_camera Step
var target_x = obj_player.x;
var target_y = obj_player.y - 100; // look ahead
camera_set_view_pos(view_camera[0], lerp(camera_get_view_x(view_camera[0]), target_x, 0.1), lerp(camera_get_view_y(view_camera[0]), target_y, 0.1));
// Clamp to room bounds

8. Level Design

  • Room per level (or large room + activation regions).
  • Tile collision layer + Instance layer (enemies, items).
  • Use Inheritance: obj_enemy_parent → obj_goomba, obj_koopa.

9. Polish Essentials

  • Coyote Time + Jump Buffer (implemented above) — critical for fairness.
  • Particle FX: Dust on land/run, stars on stomp, screen shake on death.
  • Sound Design: Pitch variation on jump/coin (audio_play_sound_at with random pitch 0.9–1.1).
  • Game Feel: 5-frame jump startup, 3-frame landing lag, 1-frame input buffer.

10. Resources

  • HeartBeast / FriendlyCosmonaut (YouTube): "Make a Platformer in GameMaker 2023".
  • GameMaker Docs: Collision Functions, Tilemap Functions, State Machines.
  • YoYo Games Tech Blog: "Platformer Collision" article.
  • GitHub: Search "GameMaker Mario Clone" for reference projects.

Start small: One room, Mario moves, jumps, collides, stomps one Goomba. Expand weekly.


https://www.htfbw.com © HT Games