Kill player when gate closes on them.

This commit is contained in:
David Thompson 2024-05-22 09:29:44 -04:00
parent 68b427e387
commit 71d62e596e
3 changed files with 88 additions and 38 deletions

BIN
assets/sounds/die.wav Normal file

Binary file not shown.

View file

@ -68,6 +68,7 @@
(define audio:no (load-sound-effect "no")) (define audio:no (load-sound-effect "no"))
(define audio:exit (load-sound-effect "exit")) (define audio:exit (load-sound-effect "exit"))
(define audio:pickup (load-sound-effect "pickup")) (define audio:pickup (load-sound-effect "pickup"))
(define audio:die (load-sound-effect "die"))
;; Game state ;; Game state
(define *state* #f) (define *state* #f)
@ -198,10 +199,16 @@
(define (move-player dir) (define (move-player dir)
(define (do-move) (define (do-move)
(with-goblins (with-goblins
($ (level-player *level*) 'move dir) (let ((player (level-player *level*)))
(if ($ player 'alive?)
(begin
($ player 'move dir)
($ (level-actor *level*) 'tick) ($ (level-actor *level*) 'tick)
(define result ;; TODO: Need a better way to receive events to play sounds
(match ($ (level-player *level*) 'event) ;; and emit particles and stuff so any actor can trigger
;; events.
(let ((result
(match ($ player 'event)
(('bump) (('bump)
(media-play audio:bump) (media-play audio:bump)
#f) #f)
@ -211,16 +218,22 @@
(('exit) (('exit)
(media-play audio:exit) (media-play audio:exit)
'next-level) 'next-level)
(('die)
(media-play audio:die)
#f)
(('gem) (('gem)
(media-play audio:pickup) (media-play audio:pickup)
;; TODO: Maybe show a little achievement popup when all gems ;; TODO: Maybe show a little achievement popup when all gems
;; are collected? ;; are collected?
(set! *gems* (cons *level-idx* *gems*)) (set! *gems* (cons *level-idx* *gems*))
#f) #f)
(_ #f))) (_ #f))))
(update-objects!) (update-objects!)
result))
(save-snapshot!) (save-snapshot!)
result))
(begin
(media-play audio:no)
#f)))))
(when (eq? (do-move) 'next-level) (when (eq? (do-move) 'next-level)
(next-level!))) (next-level!)))

View file

@ -39,6 +39,7 @@
(('type) 'exit) (('type) 'exit)
(('position) position) (('position) position)
(('tick grid-info) #f) (('tick grid-info) #f)
(('post-tick grid-info) #f)
(('enter obj grid-info) #f) (('enter obj grid-info) #f)
(('exit obj grid-info) #f) (('exit obj grid-info) #f)
(('wire-state) #f) (('wire-state) #f)
@ -54,6 +55,7 @@
(('type) 'wall) (('type) 'wall)
(('position) position) (('position) position)
(('tick grid-info) #f) (('tick grid-info) #f)
(('post-tick grid-info) #f)
(('enter obj grid-info) #f) (('enter obj grid-info) #f)
(('exit obj grid-info) #f) (('exit obj grid-info) #f)
(('wire-state) (('wire-state)
@ -80,6 +82,7 @@
(('type) 'block) (('type) 'block)
(('position) ($ position)) (('position) ($ position))
(('tick grid-info) ($ pushed? #f)) (('tick grid-info) ($ pushed? #f))
(('post-tick grid-info) #f)
(('enter obj grid-info) #f) (('enter obj grid-info) #f)
(('exit obj grid-info) #f) (('exit obj grid-info) #f)
(('wire-state) (('wire-state)
@ -123,6 +126,7 @@
(('type) 'emitter) (('type) 'emitter)
(('position) position) (('position) position)
(('tick grid-info) ($ timer (+ ($ timer) 1))) (('tick grid-info) ($ timer (+ ($ timer) 1)))
(('post-tick grid-info) #f)
(('enter obj grid-info) #f) (('enter obj grid-info) #f)
(('exit obj grid-info) #f) (('exit obj grid-info) #f)
(('wire-state) (('wire-state)
@ -155,6 +159,7 @@
(('type) 'switch) (('type) 'switch)
(('position) position) (('position) position)
(('tick grid-info) #f) (('tick grid-info) #f)
(('post-tick grid-info) #f)
(('enter obj grid-info) (('enter obj grid-info)
($ on? #t)) ($ on? #t))
(('exit obj grid-info) (('exit obj grid-info)
@ -181,6 +186,7 @@
(('type) 'switch) (('type) 'switch)
(('position) position) (('position) position)
(('tick grid-info) #f) (('tick grid-info) #f)
(('post-tick grid-info) #f)
(('enter obj grid-info) #f) (('enter obj grid-info) #f)
(('exit obj grid-info) #f) (('exit obj grid-info) #f)
(('wire-state) #f) (('wire-state) #f)
@ -210,6 +216,7 @@
(('type) 'gem) (('type) 'gem)
(('position) position) (('position) position)
(('tick grid-info) #f) (('tick grid-info) #f)
(('post-tick grid-info) #f)
(('enter obj grid-info) #f) (('enter obj grid-info) #f)
(('exit obj grid-info) #f) (('exit obj grid-info) #f)
(('wire-state) #f) (('wire-state) #f)
@ -227,6 +234,7 @@
(('type) 'gate) (('type) 'gate)
(('position) position) (('position) position)
(('tick grid-info) #f) (('tick grid-info) #f)
(('post-tick grid-info) #f)
(('enter obj grid-info) #f) (('enter obj grid-info) #f)
(('exit obj grid-info) #f) (('exit obj grid-info) #f)
(('activate) ($ open? #t)) (('activate) ($ open? #t))
@ -245,6 +253,7 @@
(('type) 'emitter) (('type) 'emitter)
(('position) position) (('position) position)
(('tick grid-info) #f) (('tick grid-info) #f)
(('post-tick grid-info) #f)
(('enter obj grid-info) #f) (('enter obj grid-info) #f)
(('exit obj grid-info) #f) (('exit obj grid-info) #f)
(('wire-state) ($ state)) (('wire-state) ($ state))
@ -268,6 +277,7 @@
(define (^player bcom x y) (define (^player bcom x y)
(define position (spawn ^cell (vector x y 2))) (define position (spawn ^cell (vector x y 2)))
(define velocity (spawn ^cell #(0 0))) (define velocity (spawn ^cell #(0 0)))
(define alive? (spawn ^cell #t))
(define event (spawn ^cell)) (define event (spawn ^cell))
(match-lambda* (match-lambda*
(('type) 'player) (('type) 'player)
@ -281,18 +291,39 @@
('down #(0 1)) ('down #(0 1))
(_ (error "invalid direction" dir))))) (_ (error "invalid direction" dir)))))
(('tick grid-info) (('tick grid-info)
($ event #f) ;; Search for objects that were fine to step onto last turn, but
;; have become deadly this turn. If
(match ($ position) (match ($ position)
(#(x y z) (#(x y z)
($ event #f)
(match ($ velocity) (match ($ velocity)
(#(dx dy) (#(dx dy)
($ position (vector (+ x dx) (+ y dy) z)) ($ position (vector (+ x dx) (+ y dy) z))
($ velocity #(0 0))))))) ($ velocity #(0 0)))))))
(('post-tick grid-info)
(match ($ position)
(#(x y z)
(let lp ((objs ($ grid-info 'occupants x y)))
(match objs
;; All is well. Move by current velocity.
(()
(match ($ velocity)
(#(dx dy)
($ position (vector (+ x dx) (+ y dy) z))
($ velocity #(0 0)))))
((obj . rest)
(match ($ obj 'type)
('gate
;; Ouch, a gate closed on the player!
(unless ($ obj 'open?)
($ alive? #f)
($ event '(die))))
(_ (lp rest)))))))))
(('enter obj grid-info) #f) (('enter obj grid-info) #f)
(('exit obj grid-info) #f) (('exit obj grid-info) #f)
(('wire-state) #f) (('wire-state) #f)
(('update-wire-state grid-info) #f) (('update-wire-state grid-info) #f)
(('alive?) #t) (('alive?) ($ alive?))
(('describe) `(player ,($ position))) (('describe) `(player ,($ position)))
(('collide other offset grid-info) (('collide other offset grid-info)
(define (reverse-move) (define (reverse-move)
@ -451,28 +482,34 @@
(unless (equal? other-pos other-prev-pos) (unless (equal? other-pos other-prev-pos)
(collide other other-pos other-prev-pos))) (collide other other-pos other-prev-pos)))
(lp rest)))))))))))) (lp rest))))))))))))
(define (tick) (define (iter-objects proc)
;; Tick each object and check for collisions.
($ objects ($ objects
(let lp ((objs ($ objects))) (let lp ((objs ($ objects)))
(match objs (match objs
(() '()) (() '())
((obj . rest) ((obj . rest)
(proc obj)
;; Cull dead objects.
(if ($ obj 'alive?)
(cons obj (lp rest))
(lp rest)))))))
(define (tick)
;; Tick each object and check for collisions.
(iter-objects
(lambda (obj)
(let ((prev-pos ($ obj 'position))) (let ((prev-pos ($ obj 'position)))
($ obj 'tick grid-info) ($ obj 'tick grid-info)
;; Only check collisions for movable objects. ;; Only check collisions for movable objects.
(let ((desired-pos ($ obj 'position))) (let ((desired-pos ($ obj 'position)))
(unless (equal? prev-pos desired-pos) (unless (equal? prev-pos desired-pos)
(collide obj desired-pos prev-pos))) (collide obj desired-pos prev-pos))))))
;; Cull dead objects.
(if ($ obj 'alive?)
(cons obj (lp rest))
(lp rest)))))))
;; Advance Wirewold simulation. ;; Advance Wirewold simulation.
(refresh-wire-grid) (refresh-wire-grid)
(for-each (lambda (obj) (for-each (lambda (obj)
($ obj 'update-wire-state grid-info)) ($ obj 'update-wire-state grid-info))
($ objects))) ($ objects))
;; Run post-tick hooks.
(iter-objects (lambda (obj) ($ obj 'post-tick grid-info))))
(match-lambda* (match-lambda*
(('tick) (tick)) (('tick) (tick))