diff options
author | David Thompson <dthompson@vistahigherlearning.com> | 2020-04-14 17:02:17 -0400 |
---|---|---|
committer | David Thompson <dthompson@vistahigherlearning.com> | 2020-04-14 17:02:17 -0400 |
commit | f08e14fd51e2b1f5920ac6816774c5e72cbee5c0 (patch) | |
tree | 3ed2df4b9c78ca2872b8af2aa91ed3dbff004351 /lisparuga | |
parent | 2bdb665cffff93721bbd38b3809a7c420dff2f1c (diff) |
Day 4 progress.
Diffstat (limited to 'lisparuga')
-rw-r--r-- | lisparuga/enemy.scm | 12 | ||||
-rw-r--r-- | lisparuga/game.scm | 184 | ||||
-rw-r--r-- | lisparuga/node.scm | 5 | ||||
-rw-r--r-- | lisparuga/player.scm | 45 |
4 files changed, 161 insertions, 85 deletions
diff --git a/lisparuga/enemy.scm b/lisparuga/enemy.scm index aa5335e..06533ea 100644 --- a/lisparuga/enemy.scm +++ b/lisparuga/enemy.scm @@ -49,6 +49,7 @@ ;;; (define-asset explosion-sound (load-audio (scope-asset "sounds/explosion.wav"))) +(define-asset hit-sound (load-audio (scope-asset "sounds/hit.wav"))) (define-class <enemy> (<actor>) (health #:accessor health #:init-keyword #:health) @@ -56,15 +57,14 @@ (parting-shots #:getter parting-shots #:init-keyword #:parting-shots) (fire-parting-shots? #:accessor fire-parting-shots? #:init-form #f)) -(define-method (on-kill (enemy <enemy>)) - #t) - (define-method (damage (enemy <enemy>) x) (let ((new-health (max (- (health enemy) x) 0))) (set! (health enemy) new-health) - (when (zero? new-health) - (audio-play (asset-ref explosion-sound) - #:volume 0.5)))) + (if (zero? new-health) + (audio-play (asset-ref explosion-sound) + #:volume 0.5) + (audio-play (asset-ref hit-sound) + #:volume 0.5)))) (define-method (dead? (enemy <enemy>)) (zero? (health enemy))) diff --git a/lisparuga/game.scm b/lisparuga/game.scm index 9e79898..f5b3082 100644 --- a/lisparuga/game.scm +++ b/lisparuga/game.scm @@ -23,6 +23,7 @@ (define-module (lisparuga game) #:use-module (chickadee) + #:use-module (chickadee math) #:use-module (chickadee math rect) #:use-module (chickadee math vector) #:use-module (chickadee render color) @@ -62,7 +63,16 @@ ;; scrolling background (define-class <game> (<canvas>) (player-control? #:accessor player-control? #:init-value #f) - (complete? #:accessor complete? #:init-value #f)) + (complete? #:accessor complete? #:init-value #f) + (skip-tutorial? #:accessor skip-tutorial? #:init-value #f)) + +(define-method (reset (game <game>)) + (set! (player-control? game) #f) + (set! (complete? game) #f) + (reset (& game player)) + (for-each detach (children (& game enemies))) + (let ((battle-report (& game battle-report))) + (and battle-report (detach battle-report)))) (define-method (initialize (game <game>) initargs) (next-method) @@ -81,6 +91,7 @@ #:rank 2 #:capacity 500 #:texture-atlas player-bullet-atlas)) + (player (make-player player-bullets)) (enemy-bullets (make <bullet-field> #:name 'enemy-bullets #:rank 5 @@ -98,11 +109,13 @@ (ui (make <node-2d> #:name 'ui #:rank 999))) + (set! (rank player) 1) (attach-to game (make <sprite> #:name 'clouds #:rank 0 #:texture clouds) + player player-bullets (make <node-2d> #:name 'enemies @@ -128,26 +141,11 @@ #:align 'right) (make <label> #:name 'lives - #:position (vec2 2.0 2.0))) - (start-stage game))) + #:position (vec2 2.0 2.0))))) (define-method (start-stage (game <game>)) - (let ((player (make-player (& game player-bullets)))) - (set! (rank player) 1) - (attach-to game player) - (update-ui game) - (play-stage-1 game))) - -(define-method (spawn-enemies (game <game>)) - ;; Test enemies - (spawn-enemy game (make-utatsugumi 'white 10.0 180.0)) - (spawn-enemy game (make-utatsugumi 'white 30.0 180.0)) - (spawn-enemy game (make-utatsugumi 'white 50.0 180.0)) - (spawn-enemy game (make-utatsugumi 'black 70.0 180.0)) - (spawn-enemy game (make-utatsugumi 'black 90.0 180.0)) - (spawn-enemy game (make-utatsugumi 'black 110.0 180.0)) - (spawn-enemy game (make-utatsugumi 'white 130.0 180.0)) - (spawn-enemy game (make-utatsugumi 'white 150.0 180.0))) + (update-ui game) + (play-stage-1 game)) (define-method (update-ui (game <game>)) (set! (text (& game ui score)) @@ -178,26 +176,25 @@ (define-method (update (game <game>) dt) (let ((refresh-ui? #f) (player (& game player))) - (when player - ;; enemy -> player bullet collision - ;; enemy -> player collision - (for-each (lambda (enemy) - (cond - ((and (collide (& game player-bullets) enemy) - (dead? enemy)) - (on-kill player enemy) - (fire-parting-shots-maybe enemy player) - (explode game enemy) - (detach enemy) - (set! refresh-ui? #t)) - ((collide player enemy) - (set! refresh-ui? #t)))) - (children (& game enemies))) - ;; player -> enemy bullet collision - (when (collide (& game enemy-bullets) (& game player)) - (set! refresh-ui? #t)) - (when refresh-ui? - (update-ui game))) + ;; enemy -> player bullet collision + ;; enemy -> player collision + (for-each (lambda (enemy) + (cond + ((and (collide (& game player-bullets) enemy) + (dead? enemy)) + (on-kill player enemy) + (fire-parting-shots-maybe enemy player) + (explode game enemy) + (detach enemy) + (set! refresh-ui? #t)) + ((collide player enemy) + (set! refresh-ui? #t)))) + (children (& game enemies))) + ;; player -> enemy bullet collision + (when (collide (& game enemy-bullets) (& game player)) + (set! refresh-ui? #t)) + (when refresh-ui? + (update-ui game)) (next-method))) (define-method (spawn-enemy (game <game>) enemy) @@ -226,8 +223,7 @@ (update-ui game))) (define-method (game-over? (game <game>)) - (let ((player (& game player))) - (and player (dead? player)))) + (dead? (& game player))) (define-method (play-stage-1 game) (run-script game @@ -244,8 +240,6 @@ (set! (player-control? game) #t) (show (& game ui))) -(define *skip-tutorial?* #t) - (define-method (do-tutorial (game <game>)) (define* (instruct text continue? #:optional (post-delay 60)) (let ((instructions (make <label> @@ -259,7 +253,7 @@ (sleep post-delay) (detach instructions) (sleep 60))) - (unless *skip-tutorial?* + (unless (skip-tutorial? game) (sleep 30) (instruct "use arrow keys to move" (let ((v (velocity (& game player)))) @@ -269,7 +263,7 @@ (instruct "press Z to shoot" (lambda () (shooting? (& game player)))) - (instruct "press X to change color" + (instruct "press X to change energy" (let ((starting-polarity (polarity (& game player)))) (lambda () (not (eq? (polarity (& game player)) starting-polarity))))) @@ -280,28 +274,72 @@ (instruct "press C to release energy" (lambda () (zero? (energy (& game player))))) - (instruct "get ready!" (const #t) 120))) + (instruct "shoot opposite energy" (const #t) 90) + (instruct "deal 2x damage" (const #t) 90) + (set! (invincible? (& game player)) #t) + (spawn-enemy game (make-utatsugumi 'white 48.0 150.0)) + (spawn-enemy game (make-utatsugumi 'white 80.0 150.0)) + (spawn-enemy game (make-utatsugumi 'white 112.0 150.0)) + (instruct "destroy 3 of same energy" + (lambda () + (null? (children (& game enemies))))) + (spawn-enemy game (make-utatsugumi 'black 48.0 150.0)) + (spawn-enemy game (make-utatsugumi 'black 80.0 150.0)) + (spawn-enemy game (make-utatsugumi 'black 112.0 150.0)) + (instruct "repeat for chain bonus" + (lambda () + (null? (children (& game enemies))))) + (set! (score (& game player)) 0) + (set! (chain (& game player)) 0) + (set! (chain-progress (& game player)) '()) + (set! (max-chain (& game player)) 0) + (set! (energy (& game player)) 0) + (set! (invincible? (& game player)) #f) + (update-ui game) + (instruct "get ready!" (const #t) 120) + (set! (skip-tutorial? game) #t))) (define-method (do-phase-1 (game <game>)) - (define (utatsugumi-sweep x polarity) - (let loop ((i 0)) - (when (< i 6) - (let ((utatsugumi (make-utatsugumi polarity x 260.0))) - (spawn-enemy game utatsugumi) - (set-vec2! (velocity utatsugumi) 0.0 -3.0) - (script - (sleep (* 10 60)) - (detach utatsugumi)) - (sleep 10)) - (loop (+ i 1))))) - (utatsugumi-sweep 140.0 'white) - (sleep 60) - (utatsugumi-sweep 20.0 'black) - (sleep 60) - (utatsugumi-sweep 140.0 'white) - (sleep 60) - (utatsugumi-sweep 20.0 'black) - (sleep (* 3 60))) + (define (utatsugumi-sweep x dir polarity) + (let ((speed 3.0)) + (let loop ((i 0)) + (when (< i 6) + (let ((utatsugumi (make-utatsugumi polarity x 260.0))) + (spawn-enemy game utatsugumi) + (set-vec2! (velocity utatsugumi) + (* (cos (* pi 1.5)) speed) + (* (sin (* pi 1.5)) speed)) + (script + (sleep 5) + (let loop ((i 0)) + (when (< i 25) + (let ((theta (+ (* pi 1.5) + (* dir i (/ (* pi .5) 25.0))))) + (set-vec2! (velocity utatsugumi) + (* (cos theta) speed) + (* (sin theta) speed)) + (sleep 3) + (loop (+ i 1))))) + (sleep 60) + (detach utatsugumi)) + (sleep 15)) + (loop (+ i 1)))))) + (utatsugumi-sweep 140.0 -1.0 'white) + (sleep 15) + (utatsugumi-sweep 20.0 1.0 'black) + (sleep 15) + (utatsugumi-sweep 140.0 -1.0 'white) + (sleep 15) + (utatsugumi-sweep 20.0 1.0 'black) + (sleep 15) + (utatsugumi-sweep 140.0 -1.0 'white) + (sleep 15) + (utatsugumi-sweep 20.0 1.0 'black) + (sleep 15) + (utatsugumi-sweep 140.0 -1.0 'white) + (sleep 15) + (utatsugumi-sweep 20.0 1.0 'black) + (sleep 60)) (define-method (do-win (game <game>)) (set! (player-control? game) #f) @@ -331,21 +369,29 @@ (lambda (c) (set! (color backdrop) c)) #:interpolate color-lerp)) + (sleep 30) + (attach-to battle-report + (make <label> + #:rank 999 + #:text "STAGE CLEAR!" + #:align 'center + #:position (vec2 80.0 190.0))) + (sleep 30) (attach-to battle-report (make <label> #:rank 999 #:text "BATTLE REPORT" #:align 'center - #:position (vec2 80.0 180.0))) + #:position (vec2 80.0 145.0))) (sleep 30) - (add-row 140.0 "SCORE" (number->string (score (& game player)))) + (add-row 120.0 "SCORE" (number->string (score (& game player)))) (sleep 30) - (add-row 110.0 "MAX CHAIN" (number->string (max-chain (& game player)))) + (add-row 100.0 "MAX CHAIN" (number->string (max-chain (& game player)))) (sleep 30) (attach-to battle-report (make <label> #:rank 999 #:text "press ENTER to play again" - #:position (vec2 80.0 60.0) + #:position (vec2 80.0 40.0) #:align 'center)) (set! (complete? game) #t))) diff --git a/lisparuga/node.scm b/lisparuga/node.scm index 2dbbd41..0939336 100644 --- a/lisparuga/node.scm +++ b/lisparuga/node.scm @@ -168,8 +168,9 @@ represented as a ratio in the range [0, 1]." ;; First time activating? We must boot! (unless (booted? node) (boot node)) (set! (active? node) #t) - (on-enter node) - (for-each-child activate node)) + (for-each-child activate node) + ;; Activate all children, recursively, before calling on-enter hook. + (on-enter node)) (define-method (deactivate (node <node>)) "Mark NODE and all of its children as inactive." diff --git a/lisparuga/player.scm b/lisparuga/player.scm index 1265756..6a85cc4 100644 --- a/lisparuga/player.scm +++ b/lisparuga/player.scm @@ -54,12 +54,15 @@ fire-homing-missiles kill-maybe on-kill - add-energy)) + add-energy + reset)) (define-asset ship-atlas (load-tile-atlas (scope-asset "images/player.png") 24 24)) (define-asset shoot-sound (load-audio (scope-asset "sounds/player-shoot.wav"))) (define-asset missile-sound (load-audio (scope-asset "sounds/player-missile.wav"))) (define-asset death-sound (load-audio (scope-asset "sounds/player-death.wav"))) +(define-asset energy-max-sound (load-audio (scope-asset "sounds/energy-max.wav"))) +(define-asset max-chain-sound (load-audio (scope-asset "sounds/max-chain.wav"))) (define kill-hitbox (make-hitbox 'kill (make-rect -2.0 -2.0 4.0 4.0))) (define graze-hitbox (make-hitbox 'graze (make-rect -12.0 -12.0 24.0 24.0))) @@ -76,6 +79,20 @@ (shooting? #:accessor shooting? #:init-value #f) (shoot-time #:accessor shoot-time #:init-value 0)) +(define-method (reset (player <player>)) + (set! (polarity player) 'white) + (set-vec2! (velocity player) 0.0 0.0) + (set! (score player) 0) + (set! (lives player) 3) + (set! (energy player) 0) + (set! (chain player) 0) + (set! (chain-progress player) '()) + (set! (max-chain player) 0) + (set! (invincible? player) #f) + (set! (shooting? player) #f) + (set! (shoot-time player) 0) + (refresh-sprite player)) + (define-method (dead? (player <player>)) (zero? (lives player))) @@ -95,7 +112,7 @@ #:index 0 #:origin (vec2 12.0 12.0)))) -(define (shoot player ox) +(define-method (shoot (player <player>) ox) (let ((speed 8.0) (pos (position player)) (bullets (bullet-field player)) @@ -151,12 +168,16 @@ (vec2-mult! v (speed player)))) (define-method (start-shooting (player <player>)) - (set! (shooting? player) #t) - (set! (shoot-time player) 0)) + (unless (shooting? player) + (set! (shooting? player) #t) + (set! (shoot-time player) 0))) (define-method (stop-shooting (player <player>)) (set! (shooting? player) #f)) +(define-method (refresh-sprite (player <player>)) + (set! (index (& player ship)) (if (eq? (polarity player) 'white) 0 4))) + (define-method (toggle-polarity (player <player>)) (let ((old (polarity player))) ;; If polarity is none it means we are already switching so ignore @@ -168,8 +189,7 @@ (set! (polarity player) 'none) (sleep 7) (set! (polarity player) (if (eq? old 'white) 'black 'white)) - ;; Change sprite - (set! (index (& player ship)) (if (eq? old 'white) 4 0)))))) + (refresh-sprite player))))) (define-method (fire-homing-missiles (player <player>) enemies) (let* ((e (energy player)) @@ -247,7 +267,12 @@ #t)) (define-method (add-energy (player <player>) n) - (set! (energy player) (min (+ (energy player) n) 120))) + (let* ((old-energy (energy player)) + (new-energy (min (+ old-energy n) 120))) + (set! (energy player) new-energy) + (when (and (not (= old-energy new-energy)) + (= new-energy 120)) + (audio-play (asset-ref energy-max-sound))))) (define-method (kill-maybe (player <player>)) (unless (invincible? player) @@ -255,6 +280,8 @@ (let ((new-lives (max (- (lives player) 1) 0))) (set! (lives player) new-lives) (set! (energy player) 0) + (set! (chain-progress player) '()) + (set! (chain player) 0) (if (zero? new-lives) (begin ;; to stop the death events from happening over and over @@ -317,7 +344,9 @@ ;; - 7 Chain --- 6,400 points ;; - 8 Chain --- 12,800 points ;; - 9+ Chain -- 25,600 points - (* (expt 2 (- (min new-chain 9) 1)) 100))))) + (* (expt 2 (- (min new-chain 9) 1)) 100))) + (when (>= new-chain 9) + (audio-play (asset-ref max-chain-sound))))) ;; 1st or 2nd kill of the chain. ((or ('white) ('black) ('white 'white) ('black 'black)) (set! (chain-progress player) current-chain)) |