diff options
-rw-r--r-- | game.scm | 123 |
1 files changed, 104 insertions, 19 deletions
@@ -101,7 +101,7 @@ (define-record-type* <world> %make-world make-world world? - (level world-level #f) + (waves world-waves #f) (stats world-stats (make-stats)) (player world-player (make-actor (make-player) idle)) (player-bullets world-player-bullets '()) @@ -444,6 +444,19 @@ ;;; Game world simulation ;;; +(define (final-wave? world) + (= (length (world-waves world)) 1)) + +(define (game-over? world) + (zero? (stats-lives (world-stats world)))) + +(define (game-won? world) + (and (null? (world-waves world)) + (not (game-over? world)))) + +(define (game-intro? world) + (not (world-waves world))) + (define (keep-bullet? bullet) (and (bullet-live? bullet) (bullet-in-bounds? bullet))) @@ -470,24 +483,35 @@ (update-actor world effects (world-player world))) (define (update-world world time) - ;; TODO: collision detection (let*-values - (((effects new-player) (update-player '() world)) + (((game-over?) (game-over? world)) + ((effects new-player) + (if game-over? + (values '() (world-player world)) + (update-player '() world))) ((effects new-enemies) (update-enemies effects world)) ((effects new-player-bullets) - (update-bullets effects world (world-player-bullets world))) + (if game-over? + (values effects '()) + (update-bullets effects world (world-player-bullets world)))) ((effects new-enemy-bullets) (update-bullets effects world (world-enemy-bullets world))) ((stats) (world-stats world)) ((new-enemies new-player-bullets new-stats explosions1) - (collide-enemies-and-bullets new-enemies new-player-bullets - stats time)) - ((new-player new-enemy-bullets new-stats explosions3) - (collide-player-and-bullets new-player new-enemy-bullets - new-stats time)) - ((new-player new-stats explosions2) - (collide-player-and-enemies new-player new-enemies - new-stats time)) + (if game-over? + (values new-enemies new-player-bullets stats '()) + (collide-enemies-and-bullets new-enemies new-player-bullets + stats time))) + ((new-player new-enemy-bullets new-stats explosions2) + (if game-over? + (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) + (if game-over? + (values new-player new-stats '()) + (collide-player-and-enemies new-player new-enemies + new-stats time))) ((new-explosions) (filter (lambda (explosion) (explosion-active? explosion time)) @@ -500,6 +524,7 @@ #:player-bullets new-player-bullets #:enemies new-enemies #:enemy-bullets new-enemy-bullets + #:waves (world-waves world) #:stats new-stats #:explosions new-explosions)))) @@ -521,10 +546,16 @@ (('player-toggle-polarity) (make-world #:inherit world #:player (call-with-actor (world-player world) - toggle-polarity))))) - -(define (game-over? world) - (zero? (stats-lives (world-stats world)))) + toggle-polarity))) + (('restart restart?) + (if (and restart? + (or (game-over? world) + (game-won? world) + (game-intro? world))) + (make-world #:inherit %default-world + #:waves '(foo) + #:enemies (list %default-enemy)) + world)))) (define player-shoot* (action-effect-lift player-shoot)) (define move-enemy* (action-lift move-enemy)) @@ -577,7 +608,9 @@ (signal-filter identity #f (signal-drop-repeats (key-down? 'x))))) - `(player-toggle-polarity))))) + `(player-toggle-polarity)) + (signal-let ((restart? (key-down? 'return))) + `(restart ,restart?))))) (define (key-toggle key) "Create a signal that is initially #f and toggles between #t and #f @@ -621,6 +654,10 @@ each time KEY is pressed." (on-start (load-font "assets/fonts/kenpixel_mini.ttf" 7))) +(define-signal big-font + (on-start + (load-font "assets/fonts/kenpixel_mini.ttf" 16))) + (define font-color (rgb #xdeeed6)) (define-signal fps-text @@ -673,6 +710,50 @@ each time KEY is pressed." #:anchor 'top-left))) render-nothing))) +(define render-status-text + (memoize + (lambda (font text) + (render-sprite + (make-label font text #:blended? #f #:anchor 'center))))) + +(define-signal status-text + (signal-let ((big-font big-font) + (font font) + (world world)) + (cond + ((or (not font) (not big-font)) + render-nothing) + ((game-over? world) + (move (v* resolution 0.5) + (render-begin + (render-status-text big-font "GAME OVER") + (move (vector2 0 -16) + (render-status-text font "Press ENTER to play again")) + (move (vector2 0 -28) + (render-status-text font "Press ESC to quit"))))) + ((game-won? world) + (move (v* resolution 0.5) + (render-begin + (render-status-text big-font "COMPLETE!") + (move (vector2 0 -16) + (render-status-text font "Press ENTER to play again")) + (move (vector2 0 -28) + (render-status-text font "Press ESC to quit"))))) + ((game-intro? world) + (move (v* resolution (vector2 0.5 0.8)) + (render-begin + (render-status-text font "Use arrow keys to move") + (move (vector2 0 -12) + (render-status-text font "Press Z to shoot")) + (move (vector2 0 -24) + (render-status-text font "Press X to change polarity")) + (move (vector2 0 -36) + (render-status-text font "Press ESC to quit")) + (move (vector2 0 -60) + (render-status-text big-font "Press ENTER"))))) + (else + render-nothing)))) + (define load-sprite/live (with-live-reload load-sprite)) (define load-tileset/live (with-live-reload load-tileset)) @@ -840,6 +921,7 @@ each time KEY is pressed." (score-text score-text) (lives-text lives-text) (chain-text chain-text) + (status-text status-text) (display-fps? display-fps?) (background scrolling-background) (framebuffer framebuffer) @@ -867,7 +949,9 @@ each time KEY is pressed." (render-bullets (world-player-bullets world) bullet-tileset batch) - (render-player player player-sprite time) + (if (game-over? world) + render-nothing + (render-player player player-sprite time)) (render-enemies (world-enemies world) enemy-tileset batch @@ -882,7 +966,8 @@ each time KEY is pressed." render-nothing) score-text lives-text - chain-text)) + chain-text + status-text)) chain-sprite))) (with-camera scaled-camera (scale resolution-scale (render-sprite framebuffer-sprite))))) |