From dd429de48337800171c9cad7dd1b29bb05f21817 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Sat, 7 May 2016 14:50:18 -0400 Subject: Add waves and tweak win conditions. --- game.scm | 112 +++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 84 insertions(+), 28 deletions(-) (limited to 'game.scm') diff --git a/game.scm b/game.scm index 0f7b111..d48a62e 100644 --- a/game.scm +++ b/game.scm @@ -76,7 +76,7 @@ (aim enemy-aim 0) ; angle for firing bullets ;; TODO: We could leave out the '-light' part and use the polarity ;; field to figure things out, but it's more work so forget it. - (type enemy-type 'popcorn-light) + (type enemy-type 'pincer-dark) (polarity enemy-polarity 'light) (hitbox enemy-hitbox (make-rect -3 -3 6 6)) (last-hit-time enemy-last-hit-time #f) @@ -223,22 +223,41 @@ (make-enemy #:inherit enemy #:position (v+ (enemy-position enemy) offset))) +(define (aim-enemy enemy offset) + (make-enemy #:inherit enemy + #:aim (+ (enemy-aim enemy) offset))) + (define (add-enemy-bullets world bullets) (make-world #:inherit world #:enemy-bullets (append bullets (world-enemy-bullets world)))) +(define (add-enemy-bullet world bullet) + (make-world #:inherit world + #:enemy-bullets + (cons bullet (world-enemy-bullets world)))) + (define (simple-enemy-bullet position direction speed) - (make-actor (make-bullet #:type 'enemy-basic + (make-actor (make-bullet #:type 'small-light #:position position #:direction direction) (forever (forward speed)))) -(define (enemy-shoot world enemy direction speed) - (let ((position (enemy-position enemy))) - (add-enemy-bullets world - (list - (simple-enemy-bullet position direction speed))))) +(define (enemy-shoot world enemy type speed aim-offset) + (let* ((position (enemy-position enemy)) + (bullet (make-actor (make-bullet #:type type + #:polarity (match type + ((or 'small-light + 'large-light) + 'light) + ((or 'small-dark + 'large-dark) + 'dark)) + #:position position + #:direction (+ (enemy-aim enemy) + aim-offset)) + (forever (forward speed))))) + (add-enemy-bullet world bullet))) (define (enemy-shoot-at-player world enemy speed) (let* ((v (normalize @@ -452,6 +471,7 @@ (define (game-won? world) (and (null? (world-waves world)) + (null? (world-enemies world)) (not (game-over? world)))) (define (game-intro? world) @@ -485,6 +505,7 @@ (define (update-world world time) (let*-values (((game-over?) (game-over? world)) + ((game-won?) (game-won? world)) ((effects new-player) (if game-over? (values '() (world-player world)) @@ -498,16 +519,34 @@ (update-bullets effects world (world-enemy-bullets world))) ((stats) (world-stats world)) ((new-enemies new-player-bullets new-stats explosions1) + ;; Don't allow enemies to be killed after the game has been + ;; lost because that would lead to strange things. (if game-over? (values new-enemies new-player-bullets stats '()) (collide-enemies-and-bullets new-enemies new-player-bullets stats time))) + ;; Move to the next wave, if needed. + ((new-enemies new-waves) + (let ((waves (world-waves world))) + (cond + ((not waves) + (values new-enemies #f)) + ((null? waves) + (values new-enemies '())) + ((null? new-enemies) + (values (car waves) (cdr waves))) + (else + (values new-enemies waves))))) ((new-player new-enemy-bullets new-stats explosions2) - (if game-over? + ;; Don't collide when the game has been won or lost. + (if (or game-over? game-won?) (values new-player new-enemy-bullets new-stats '()) (collide-player-and-bullets new-player new-enemy-bullets new-stats time))) ((new-player new-stats explosions3) + ;; Don't collide when the game has been lost. By definition + ;; their are no enemies when the game is won, so we don't have + ;; to worry about that case. (if game-over? (values new-player new-stats '()) (collide-player-and-enemies new-player new-enemies @@ -524,7 +563,7 @@ #:player-bullets new-player-bullets #:enemies new-enemies #:enemy-bullets new-enemy-bullets - #:waves (world-waves world) + #:waves new-waves #:stats new-stats #:explosions new-explosions)))) @@ -553,12 +592,13 @@ (game-won? world) (game-intro? world))) (make-world #:inherit %default-world - #:waves '(foo) - #:enemies (list %default-enemy)) + #:waves (list (list %default-enemy) + (list %default-enemy))) world)))) (define player-shoot* (action-effect-lift player-shoot)) (define move-enemy* (action-lift move-enemy)) +(define aim-enemy* (action-lift aim-enemy)) (define enemy-shoot* (action-effect-lift enemy-shoot)) (define enemy-shoot-at-player* (action-effect-lift enemy-shoot-at-player)) @@ -570,20 +610,39 @@ (define %default-enemy (make-actor (make-enemy #:position (vector2 60 120) - #:health 100) - (let ((v (vector2 .8 0)) - (bullet-speed 0.6) - (interval 15)) + #:health 10 + #:type 'pincer-light) + (let* ((v (vector2 .8 0)) + (bullet-speed 0.6) + (interval 15) + (shoot (together + (aim-enemy* (/ pi 32)) + (enemy-shoot* 'large-light bullet-speed 0) + (enemy-shoot* 'large-dark (/ bullet-speed 2) pi)))) (forever (sequence - (repeat interval (move-enemy* v)) - (enemy-shoot-at-player* bullet-speed) - (repeat interval (move-enemy* (v- v))) - (enemy-shoot-at-player* bullet-speed) - (repeat interval (move-enemy* (v- v))) - (enemy-shoot-at-player* bullet-speed) - (repeat interval (move-enemy* v)) - (enemy-shoot-at-player* bullet-speed)))))) + (repeat interval (together (move-enemy* v) shoot)) + (repeat interval (together (move-enemy* (v- v)) shoot)) + (repeat interval (together (move-enemy* (v- v)) shoot)) + (repeat interval (together (move-enemy* v) shoot))))))) + +(define %default-world + (make-world #:player %default-player + ;; #:enemies + ;; (list %default-enemy + ;; (call-with-actor %default-enemy + ;; (lambda (enemy) + ;; (make-enemy #:inherit enemy + ;; #:position (vector2 40 100)))) + ;; (call-with-actor %default-enemy + ;; (lambda (enemy) + ;; (make-enemy #:inherit enemy + ;; #:position (vector2 80 90)))) + ;; (call-with-actor %default-enemy + ;; (lambda (enemy) + ;; (make-enemy #:inherit enemy + ;; #:position (vector2 100 120))))) + )) ;;; @@ -594,8 +653,7 @@ (define-signal world (signal-fold world-eval - (make-world #:player %default-player - #:enemies (list %default-enemy)) + %default-world (signal-merge (make-signal '(null)) (signal-let ((time timer)) @@ -859,12 +917,10 @@ each time KEY is pressed." (bullet-position bullet))) (tex (tileset-ref tileset (match (bullet-type bullet) - ('generic 12) - ('enemy-basic 9) ('player-light 12) ('player-dark 13) ('large-light 9) - ('dark-light 8) + ('large-dark 8) ('small-light 11) ('small-dark 10))))) (sprite-batch-add! batch context tex rect))) -- cgit v1.2.3