From a102a9fb0640352d7b1160b7f97a7ada34c9488b Mon Sep 17 00:00:00 2001 From: Juliana Sims Date: Fri, 24 May 2024 15:23:34 -0400 Subject: [PATCH] Make bombs movable, update bomb rendering --- game.scm | 13 ++++--- modules/game/actors.scm | 85 ++++++++++++++++++++++++++--------------- 2 files changed, 61 insertions(+), 37 deletions(-) diff --git a/game.scm b/game.scm index e352ee9..6359e17 100644 --- a/game.scm +++ b/game.scm @@ -296,6 +296,8 @@ (play-sound-effect audio:electric-switch-off)) (('receive-electron x y) (play-sound-effect audio:warp 0.25)) + (('explosion x y) + (pk 'BOOM!)) (_ (values))) (lp rest)))) (update-objects!) @@ -366,8 +368,7 @@ (_ (draw-tile context tileset 3 x y))) (draw-wire-state pos type))) -(define (draw-brick pos exploding?) - ;; TODO use exploding for different sprite? +(define (draw-brick pos) (draw-tile context tileset 22 (vec2-x pos) (vec2-y pos))) (define (draw-clock-emitter pos) @@ -379,8 +380,8 @@ (define (draw-floor-switch pos on?) (draw-tile context tileset (if on? 25 24) (vec2-x pos) (vec2-y pos))) -(define (draw-bomb pos exploding?) - (draw-tile context tileset (if exploding? 51 50) (vec2-x pos) (vec2-y pos))) +(define (draw-bomb pos countdown) + (draw-tile context tileset (+ 51 countdown) (vec2-x pos) (vec2-y pos))) (define (draw-gem pos) (draw-tile context tileset 28 (vec2-x pos) (vec2-y pos))) @@ -418,11 +419,11 @@ (('exit pos) #t) ; drawn via background (('wall pos type) (draw-wall pos type)) (('block pos type) (draw-block pos type)) - (('brick pos exploding?) (draw-brick pos exploding?)) + (('brick pos) (draw-brick pos)) (('clock-emitter pos) (draw-clock-emitter pos)) (('switched-emitter pos on?) (draw-switched-emitter pos on?)) (('floor-switch pos on?) (draw-floor-switch pos on?)) - (('bomb pos exploding?) (draw-bomb pos exploding?)) + (('bomb pos countdown) (draw-bomb pos countdown)) (('gem pos) (draw-gem pos)) (('ghost-gem pos) (draw-ghost-gem pos)) (('gate pos open?) (draw-gate pos open?)) diff --git a/modules/game/actors.scm b/modules/game/actors.scm index 6a71606..1ce6d61 100644 --- a/modules/game/actors.scm +++ b/modules/game/actors.scm @@ -103,22 +103,18 @@ (define (^brick bcom x y) (define position (vector x y 1)) (define alive? (spawn ^cell #t)) - (define exploding? (spawn ^cell)) (match-lambda* (('type) 'brick) (('position) position) (('tick grid-info) #f) - (('post-tick grid-info) - (when ($ exploding?) - ($ alive? #f))) + (('post-tick grid-info) #f) (('enter obj grid-info) #f) (('exit obj grid-info) #f) (('wire-state grid-info from from-x from-y) #f) (('update-wire-state grid-info neighbor-grid) #f) (('alive?) ($ alive?)) - (('explode) - ($ exploding? #t)) - (('describe) `(brick ,position ,($ exploding?))) + (('explode) ($ alive? #f)) + (('describe) `(brick ,position)) (('collide other offset grid-info) #f))) ;; TODO: Maybe make separate actors for conductive vs. inert blocks. @@ -345,41 +341,67 @@ (('collide other offset grid-info) #f))) (define (^bomb bcom x y) - (define position (vector x y 2)) + (define position (spawn ^cell (vector x y 1))) (define alive? (spawn ^cell #t)) - (define lit? (spawn ^cell)) - (define exploding? (spawn ^cell)) + (define countdown (spawn ^cell -1)) + (define pushed? (spawn ^cell)) (match-lambda* (('type) 'bomb) - (('position) position) + (('position) ($ position)) (('tick grid-info) - (cond - (($ exploding?) + ($ pushed? #f) + (when (> ($ countdown) 0) + ($ countdown (- ($ countdown) 1))) + (when (= ($ countdown) 0) ($ alive? #f) - (do ((ix (- x 1) (+ ix 1))) - ((> ix (+ x 1))) - (do ((iy (- y 1) (+ iy 1))) - ((> iy (+ y 1))) - (unless (and (= ix x) (= iy y)) - (let ((obj (match ($ grid-info 'occupants ix iy) - (() #f) - ((obj . rest) obj)))) - (when (and obj (eq? ($ obj 'type) 'brick)) - ($ obj 'explode))))))) - (($ lit?) - ($ exploding? #t)) - (else #f))) + (match ($ position) + (#(x y z) + (do ((ix (- x 1) (+ ix 1))) + ((> ix (+ x 1))) + (do ((iy (- y 1) (+ iy 1))) + ((> iy (+ y 1))) + (unless (and (= ix x) (= iy y)) + (let ((obj (match ($ grid-info 'occupants ix iy) + (() #f) + ((obj . rest) obj)))) + (when obj + (match ($ obj 'type) + ('brick + ($ obj 'explode)) + ('player + ($ obj 'explode) + ($ grid-info 'append-event `(player-death ,ix ,iy))) + (_ #f))))))) + ($ grid-info 'append-event `(explosion ,x ,y)))))) (('post-tick grid-info) #f) (('enter obj grid-info) #f) (('exit obj grid-info) #f) (('wire-state grid-info from from-x from-y) #f) (('update-wire-state grid-info neighbor-grid) - (when (and (not ($ lit?)) + (when (and (< ($ countdown) 0) (grid-electrified? neighbor-grid)) - ($ lit? #t))) + ($ countdown 2))) (('alive?) ($ alive?)) - (('describe) `(bomb ,position ,($ exploding?))) - (('collide other offset grid-info) #f))) + (('describe) `(bomb ,($ position) ,($ countdown))) + (('collide other offset grid-info) + (when (eq? ($ other 'type) 'player) + (match ($ position) + (#(x y z) + (match offset + (#(dx dy) + (match ($ grid-info 'dimensions) + (#(w h) + (let ((x (modulo (+ x dx) w)) + (y (modulo (+ y dy) h))) + (let ((occupant-types + (map (lambda (obj) ($ obj 'type)) + ($ grid-info 'occupants x y)))) + (match occupant-types + ((or () ('switch)) + ($ pushed? #t) + ($ position (vector x y z))) + (_ #f)))))))))))) + (('pushed?) ($ pushed?)))) ;; A gem that has already been collected previously will still appear ;; in the level but it will be drawn differently. @@ -719,6 +741,7 @@ (('exit obj grid-info) #f) (('wire-state grid-info from from-x from-y) #f) (('alive?) ($ alive?)) + (('explode) ($ alive? #f)) (('describe) `(player ,($ position), ($ alive?))) (('collide other offset grid-info) (match ($ position) @@ -730,7 +753,7 @@ (match ($ other 'type) ('exit ($ grid-info 'append-event `(exit ,x ,y))) - ('block + ((or 'block 'bomb) (if ($ other 'pushed?) ($ grid-info 'append-event `(push ,x ,y)) (begin