Commit Graph

21 Commits

Author SHA1 Message Date
joren
55f1c2a382 Optimize(Level): Add change notification callbacks for draw invalidation
Level now fires callbacks when game state changes that require redrawing:
- on-coins-changed!: fired when a coin is eaten or key is picked up
- on-maze-changed!: fired when a door is removed

Exposes set-on-coins-changed! and set-on-maze-changed! messages so the
game ADT can wire these to the draw ADT's dirty flags.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 11:21:26 +01:00
joren
5b43b3c8d5 Optimize(Draw): Skip unchanged elements in draw callback
Previously every frame: cleared+redrawed 868 cells for coins, cleared+
redrawed all UI text, emptied+recreated pause layer, and swapped key
sprites repeatedly.

Now uses dirty flags and cached values:
- Coins: only redrawn when coins-dirty? is set (on coin eat/key pickup)
- Maze: only redrawn when a door is removed
- UI: only redrawn when score or time string actually changes
- Key: sprite swap happens exactly once, not every frame
- Pause: layer only modified when paused? state transitions

Exposes mark-coins-dirty! and mark-maze-dirty! messages so the game
ADT can signal changes from the level.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 11:21:20 +01:00
joren
4c98ca61c5 Implement automatic Pac-Man movement with queued direction turning
Pac-Man now moves automatically in its current direction every
pacman-speed-ms (200ms). Arrow keys queue a desired turn direction
instead of moving directly. Each movement tick:

1. Try the queued direction — if passable, turn and move that way
2. Otherwise keep moving in the current direction
3. Stop only when hitting a wall (no direction change)

New internal state:
- queued-direction: the direction the player wants to turn next
- movement-timer: accumulates delta-time, triggers move at interval

New helper:
- can-move?: checks if a direction is passable (no wall/locked door)

Changed behavior:
- key-press! now sets queued-direction instead of calling move-pacman!
- update! now drives movement via advance-pacman! on a timer
- move-pacman! no longer checks time-up? (advance-pacman! handles it)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 11:15:46 +01:00
joren
39a91a5aa0 Add pacman-speed-ms constant for automatic movement interval
Adds a 200ms movement tick rate, controlling how fast Pac-Man moves
automatically through the maze.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 11:15:11 +01:00
joren
1ac72f03a7 Fix(Animation): Drive Pac-Man mouth animation from game loop, not draw callback
The draw callback receives no delta-time, so animation was stuck at 0.
Split draw-pacman! into draw (position/rotation) and animate-pacman!
(sprite sequence advancement). Animation is now called from the game
loop which has the real delta-time.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 11:12:56 +01:00
joren
caac996acd Refactor(Structure): Move ADTs into adt/ folder, rename spel.rkt to main.rkt
New structure groups all ADT modules under adt/ directory, removing
redundant adt- prefix from filenames. Library names now read as
(pacman-project adt position) etc. All imports updated accordingly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 11:11:08 +01:00
joren
cd70055bc7 Refactor(English): Rename all files and identifiers from Dutch to English
Renamed files: constanten→constants, adt-positie→adt-position,
adt-doolhof→adt-maze, adt-sleutel→adt-key, adt-tijdslimiet→adt-timer,
adt-teken→adt-draw, adt-spel→adt-game. All message names, variables,
comments, and tests converted to English.

Also fixed counter location bug (time-label x/y were swapped).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 11:06:32 +01:00
joren
c3c3c6e86c Refactor(Cleanup): Remove old files replaced by refactored ADT architecture
Removed: coin.rkt, game-logic.rkt, game.rkt, keyboard-handler.rkt,
main-loop.rkt, maze.rkt, pacman.rkt, pause-menu.rkt, score.rkt,
screen.rkt, time-limit.rkt, key.rkt, test.rkt, game.rkt~

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:56:33 +01:00
joren
4f8719f813 Refactor(Tests): Add proper (pp1 tests) unit tests for all logic ADTs
Tests for Positie, Doolhof, Pac-Man, Score, and Tijdslimiet ADTs
using check/check-eq?/run-test from (pp1 tests) library.
Centralized test runner in alle-testen.rkt with prefix imports.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:54:43 +01:00
joren
2ce1967c85 Refactor(Entry Point): Add clean spel.rkt entry point
Instantiates maak-spel and calls start!, following snake-wpo pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:53:29 +01:00
joren
d6d62083c9 Refactor(Spel ADT): Add top-level game orchestrator with message-passing
Connects level (logic) with teken (graphics) via callbacks.
Follows snake-wpo adt-spel pattern exactly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:53:21 +01:00
joren
48948a73a8 Refactor(Teken ADT): Isolate ALL graphics into single message-passing ADT
All rendering (maze, coins, key, pacman, UI, pause) consolidated here.
Grid-to-pixel conversion happens exclusively in this ADT.
Follows snake-wpo pattern with callback registration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:53:05 +01:00
joren
40e7a2e9d9 Refactor(Level ADT): Consolidate all game logic into message-passing ADT
Combines game-logic, keyboard-handler, main-loop, and pause-menu into
single level ADT. Handles movement, collision, teleportation, coin/key
pickup, door opening, pause toggling, and time updates. No graphics.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:52:13 +01:00
joren
957c777938 Refactor(Tijdslimiet ADT): Encapsulate time limit as message-passing ADT
Pure logic ADT with verlaag!/verhoog! mutators, tijd-op? predicate,
and formatteer-tijd method. No graphics code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:51:36 +01:00
joren
41133a2f09 Refactor(Score ADT): Encapsulate score as message-passing ADT without graphics
Pure logic ADT with punten getter and verhoog! mutator.
Uses punten-per-muntje constant. No graphics code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:51:17 +01:00
joren
22394aae50 Refactor(Sleutel ADT): Encapsulate key as message-passing ADT without graphics
Pure logic ADT with positie, opgepakt? predicate, pak-op! mutator.
Random placement logic uses doolhof ADT. No graphics code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:51:06 +01:00
joren
4d74e42fe1 Refactor(Pac-Man ADT): Encapsulate Pac-Man state as message-passing ADT
Pure logic ADT with grid-based positie, richting, beweeg! method.
All sprite/animation code removed - drawing responsibility in adt-teken.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:50:49 +01:00
joren
b342eeaeff Refactor(Doolhof ADT): Encapsulate maze as message-passing ADT without graphics
Pure logic ADT with grid data, cell predicates (muur?, muntje?, etc.),
mutators (cel-set!, verwijder-deur!), and voor-elke-cel iterator.
All graphics code removed - drawing responsibility moved to adt-teken.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:50:32 +01:00
joren
2ddbb1330c Refactor(Positie ADT): Add grid-based position ADT with message-passing dispatch
Constructor maak-positie returns dispatch closure with rij/kolom getters,
rij!/kolom! mutators, vergelijk? predicate, and beweeg method.
All coordinates are in grid units, not pixels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:49:49 +01:00
joren
5870d63d9d Refactor(Constanten): Extract all magic numbers into centralized constants file
All hardcoded values (cell sizes, offsets, sprite scales, timing, score,
UI positions, cell type codes) are now named constants in an R7RS library.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:49:32 +01:00
joren
3abc9aae55 first commit 2026-03-23 10:28:54 +01:00