From 84840ede6646ed793b61cdd889d3f57ab05e9311 Mon Sep 17 00:00:00 2001 From: Gene Pasquet Date: Wed, 8 Apr 2026 01:32:55 +0100 Subject: Refactor to be functional --- demo/shmup.scm | 54 +++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) (limited to 'demo/shmup.scm') diff --git a/demo/shmup.scm b/demo/shmup.scm index 97779a8..ab09957 100644 --- a/demo/shmup.scm +++ b/demo/shmup.scm @@ -61,6 +61,10 @@ (let ((y (entity-ref e #:y 0))) (and (> y -20) (< y (+ +screen-height+ 20))))) +(define (scene-remove-dead scene) + (let ((dead (find-dead (scene-entities scene)))) + (scene-filter-entities scene (lambda (e) (not (memq e dead)))))) + ;; ── Update helpers ─────────────────────────────────────────────────────────── (define (player-vx input) @@ -72,26 +76,27 @@ (entity-set player #:x (max 0 (min (- +screen-width+ 16) (entity-ref player #:x 0))))) -(define (update-player player input scene) +(define (update-player player input) (let ((updated (chain player (entity-set _ #:vx (player-vx input)) (apply-velocity-x _) (clamp-player-x _)))) (when (input-pressed? input 'a) - (play-sound 'shoot) - (scene-add-entity scene - (make-bullet (+ (entity-ref updated #:x 0) 6) 340))) - updated)) + (play-sound 'shoot)) + (if (input-pressed? input 'a) + (values updated + (list (make-bullet (+ (entity-ref updated #:x 0) 6) 340))) + (values updated '())))) (define (move-projectile e) (chain e (entity-set _ #:x (+ (entity-ref e #:x 0) (entity-ref e #:vx 0))) (entity-set _ #:y (+ (entity-ref e #:y 0) (entity-ref e #:vy 0))))) -(define (maybe-spawn-enemy! scene) - (when (zero? (modulo *frame-count* +spawn-interval+)) - (scene-add-entity scene - (make-enemy (+ 20 (* (pseudo-random-integer 28) 20)))))) +(define (maybe-spawn-enemies) + (if (zero? (modulo *frame-count* +spawn-interval+)) + (list (make-enemy (+ 20 (* (pseudo-random-integer 28) 20)))) + '())) ;; ── Render ─────────────────────────────────────────────────────────────────── @@ -132,22 +137,21 @@ update: (lambda (game dt) (set! *frame-count* (+ *frame-count* 1)) - (let* ((input (game-input game)) - (scene (game-scene game)) - (player (car (scene-entities scene))) - (player (update-player player input scene))) - (maybe-spawn-enemy! scene) - ;; Replace player, then move all projectiles - (scene-entities-set! scene - (cons player (filter (lambda (e) (not (eq? (entity-type e) 'player))) - (scene-entities scene)))) - (scene-update-entities scene - (lambda (e) (if (eq? (entity-type e) 'player) e (move-projectile e)))) - ;; Remove bullet/enemy collisions, then out-of-bounds - (let ((dead (find-dead (scene-entities scene)))) - (scene-filter-entities scene (lambda (e) (not (memq e dead))))) - (scene-filter-entities scene - (lambda (e) (or (eq? (entity-type e) 'player) (in-bounds? e)))))) + (let* ((input (game-input game)) + (scene (game-scene game)) + (player (car (scene-entities scene)))) + (receive (player new-entities) (update-player player input) + (let* ((others (filter (lambda (e) (not (eq? (entity-type e) 'player))) + (scene-entities scene))) + (spawned (maybe-spawn-enemies)) + (all (cons player (append new-entities spawned others)))) + (game-scene-set! game + (chain (update-scene scene entities: all) + (scene-update-entities _ + (lambda (e) (if (eq? (entity-type e) 'player) e (move-projectile e)))) + (scene-remove-dead _) + (scene-filter-entities _ + (lambda (e) (or (eq? (entity-type e) 'player) (in-bounds? e)))))))))) render: (lambda (game) (for-each (cut draw-shmup-entity (game-renderer game) <>) -- cgit v1.2.3