2) Let’s Move! — Events & Input

Goal: Move the player with Arrow/WASD keys; keep within room bounds. Events Object Variables Conditionals Room Boundaries

Table of Contents

  1. Learning Targets
  2. Prerequisites & Vocabulary
  3. Teacher Setup
  4. Student Build (DnD or GML)
  5. Checks for Understanding
  6. Troubleshooting
  7. Extensions
  8. Assessment & Rubric
  9. Pseudocode (AP CSP Tie-In)
  10. Standards Bridge
  11. Exit Ticket

Learning Targets

Prerequisites

  • A project with a player sprite (e.g., spr_player).
  • An object using that sprite (e.g., obj_player) placed in a room (e.g., rm_level1).

Vocabulary

  • Event: A trigger that runs code/blocks (e.g., Key Down).
  • Step event: Runs every frame; use for continuous input.
  • Variable: A named value (e.g., moveSpeed).
  • Conditional: A logic test: if ( ... ) { ... }.

Teacher Setup (≈5 min)

  1. Ensure students have spr_player and obj_player using that sprite.
  2. Suggested room size: 1024 × 768 (or your site standard). Place obj_player near center.
  3. Remind the class: support both Arrow keys and WASD.

Student Build (Choose DnD or GML)

A. Drag-and-Drop (DnD) Path

  1. Create Event (obj_player)
    • Add Set Variable: moveSpeed = 4
    • (Optional) Ensure the sprite is set: sprite_index = spr_player
  2. Step Event (continuous input)
    • Add Set Variable: hInput = 0, vInput = 0
    • If Key Down (Right or D) → hInput = 1
    • If Key Down (Left or A) → hInput = -1
    • If Key Down (Down or S) → vInput = 1
    • If Key Down (Up or W) → vInput = -1
    • (Optional diagonal normalize) If both hInput and vInput ≠ 0, multiply each by 0.707
    • Move:
      • Set X: x = x + hInput * moveSpeed
      • Set Y: y = y + vInput * moveSpeed
    • Clamp to room bounds (use half sprite size):
      • If x < sprite_width/2 → set to sprite_width/2
      • If x > room_width - sprite_width/2 → set to that value
      • If y < sprite_height/2 → set to sprite_height/2
      • If y > room_height - sprite_height/2 → set to that value
Tip: Using half the sprite size keeps the whole sprite on screen.

B. GML (Code) Path

Create Event (obj_player)

moveSpeed = 4;

Step Event (obj_player)

// 1) Read input
var h = 0;
var v = 0;

if (keyboard_check(vk_right) || keyboard_check(ord("D"))) h += 1;
if (keyboard_check(vk_left)  || keyboard_check(ord("A"))) h -= 1;
if (keyboard_check(vk_down)  || keyboard_check(ord("S"))) v += 1;
if (keyboard_check(vk_up)    || keyboard_check(ord("W"))) v -= 1;

// 2) Optional: normalize diagonals so diagonals aren't faster
if (h != 0 && v != 0) {
    var diag = 1 / sqrt(2); // ≈ 0.707
    h *= diag;
    v *= diag;
}

// 3) Move
x += h * moveSpeed;
y += v * moveSpeed;

// 4) Clamp to room bounds using sprite size
var halfW = sprite_width  * 0.5;
var halfH = sprite_height * 0.5;

x = clamp(x, halfW, room_width  - halfW);
y = clamp(y, halfH, room_height - halfH);

Checks for Understanding

Troubleshooting

Extensions

  1. Variable speed (Sprint with Shift)
    var base = 4;
    moveSpeed = keyboard_check(vk_shift) ? 6 : base;
  2. Smooth acceleration / friction
    // Create
    vx = 0; vy = 0; accel = 0.5; maxSpeed = 4; fric = 0.85;
    
    // Step (after computing h and v)
    vx = (h != 0) ? clamp(vx + h * accel, -maxSpeed, maxSpeed) : vx * fric;
    vy = (v != 0) ? clamp(vy + v * accel, -maxSpeed, maxSpeed) : vy * fric;
    
    x += vx; y += vy;
    
    var halfW = sprite_width * 0.5, halfH = sprite_height * 0.5;
    x = clamp(x, halfW, room_width - halfW);
    y = clamp(y, halfH, room_height - halfH);
  3. Screen wrap (alternative to clamping)
    if (x < -sprite_width) x = room_width + sprite_width;
    if (x > room_width + sprite_width) x = -sprite_width;
    if (y < -sprite_height) y = room_height + sprite_height;
    if (y > room_height + sprite_height) y = -sprite_height;
  4. Controller support (map gamepad left stick with gamepad_axis_value()).

Assessment & Rubric

Success Criteria

CategoryExceedsMeetsApproaches
Input handling (3) Arrow+WASD; continuous; clean structure Works for both schemes Only one scheme or inconsistent
Movement math (3) Uses vars; diagonal normalization Uses vars; correct 4-way move Hard-coded values; jittery
Bounds (3) Robust clamping with sprite half-size Clamps reliably to room Occasional out-of-bounds
Clarity (1) Well-commented & readable Some comments / labels Minimal explanation

Pseudocode (AP CSP Tie-In)

SET moveSpeed ← 4
EVERY FRAME:
  h ← 0; v ← 0
  IF Right OR D pressed: h ← h + 1
  IF Left  OR A pressed: h ← h - 1
  IF Down  OR S pressed: v ← v + 1
  IF Up    OR W pressed: v ← v - 1

  IF h ≠ 0 AND v ≠ 0:
     h ← h / √2
     v ← v / √2

  x ← x + h * moveSpeed
  y ← y + v * moveSpeed

  x ← CLAMP(x, sprite_width/2, room_width - sprite_width/2)
  y ← CLAMP(y, sprite_height/2, room_height - sprite_height/2)

Standards Bridge (Quick)

Submission Requirements

Submit the following to Google Classroom and drop it off into google drive:

Exit Ticket (1–2 min)

  1. In one sentence, explain how clamping prevents out-of-bounds movement.
  2. Circle which is true for continuous movement: Key Down or Key Press?