🎮 Section 07: Input, States, and Core Game Logic

Section Summary

In this section, students finish the core gameplay flow in game.py. They add keyboard input handling, pause/gameover state transitions, timer-driven snake updates, and eat/collision game rules.

By the end of this section, students will have a playable game loop where controls, movement, score updates, and game-over checks all work together.

✅ Checklist

  • [ ] Update game.py imports to include Dict.
  • [ ] Add DIRECTION_BY_KEY below the Direction alias.
  • [ ] Replace handle_events() placeholder with final event flow.
  • [ ] Add _handle_keydown() to process input by state.
  • [ ] Add _toggle_pause() for pause/resume behavior.
  • [ ] Replace step_snake() placeholder with final logic.
  • [ ] Run s07_test.py to verify controls and game-state behavior.

Core Concepts

1. Event-Driven Input

Pygame sends events into a queue. handle_events() reads every event each frame. This keeps controls responsive and ensures quit/input/timer events are handled in one place.

2. Timer Events for Snake Movement

The custom snake_tick_event controls when step_snake() runs. This keeps movement tied to S.SNAKE_TPS rather than frame rate, so gameplay speed stays stable even if rendering speed changes.

3. State Machine Thinking

The game state (playing, paused, gameover) controls what actions are allowed: - Direction keys only affect the snake while playing. - Pause keys toggle between playing and paused. - Restart keys only work from gameover.

This prevents invalid actions and keeps behavior predictable.

4. Input Mapping with a Dictionary

DIRECTION_BY_KEY maps keys to movement vectors. This avoids long if/elif chains and makes control customization easier.

Because this is a new top-level mapping constant, place it near the top of game.py (with imports/type aliases), not in the middle of methods.

5. Correct Logic Order in step_snake()

Order matters: 1. Move snake. 2. Check lose conditions. 3. Check eat condition.

If this order is wrong, score and collision behavior can become inconsistent.

6. OOP Message Flow

Game coordinates "what happens next," while Snake and Food handle their own specific behavior (move, hits_self, respawn, etc.). This is a strong OOP collaboration pattern.

Code Students Will Type (game.py)

Type this code by hand so you understand how input and game logic connect.

Code image: s07-code

Detailed Code Review & Key Concepts

Top-Level Input Map

  • DIRECTION_BY_KEY centralizes key-to-direction mapping.
  • Supports both arrow keys and WASD.

This keeps input extensible and readable.

handle_events()

  • Handles quit events.
  • Routes keypresses to _handle_keydown().
  • Processes snake movement only when timer ticks and state is playing.

This method is the event hub for the whole game.

_handle_keydown()

  • Handles quit keys first.
  • Handles pause toggle keys second.
  • Handles restart only in gameover state.
  • Ignores direction changes unless state is playing.

This priority order prevents conflicting behavior.

_toggle_pause()

  • Flips only between playing and paused.
  • Leaves gameover unchanged.

This makes pause logic explicit and safe.

step_snake()

  • Moves first.
  • Checks wall/self lose conditions next.
  • Handles eating last (grow, score, respawn).

This order ensures collision outcomes are evaluated before rewards.

Test File (s07_test.py)

Use this test file to validate controls, state transitions, and step logic.

Code image: s07-test

This test file validates the new behavior in focused pieces: - Key mapping tests confirm arrow/WASD direction vectors. - Keydown/state tests verify direction changes, pause toggles, and restart behavior. - Timer-event test confirms snake updates happen only while playing. - step_snake tests verify scoring/eating, self-collision gameover, and wall-collision gameover.

Passing these tests confirms the game now has functional controls and complete core gameplay flow.