diff options
Diffstat (limited to 'lisparuga/player.scm')
-rw-r--r-- | lisparuga/player.scm | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/lisparuga/player.scm b/lisparuga/player.scm index ca57891..1265756 100644 --- a/lisparuga/player.scm +++ b/lisparuga/player.scm @@ -21,6 +21,7 @@ ;;; Code: (define-module (lisparuga player) + #:use-module (chickadee audio) #:use-module (chickadee math) #:use-module (chickadee math rect) #:use-module (chickadee math vector) @@ -42,17 +43,23 @@ energy chain chain-progress + max-chain speed + invincible? + shooting? steer start-shooting stop-shooting toggle-polarity fire-homing-missiles kill-maybe - on-kill)) + on-kill + add-energy)) -(define-asset ship (load-image (scope-asset "images/player.png"))) (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 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))) @@ -63,16 +70,20 @@ (energy #:accessor energy #:init-value 0) (chain #:accessor chain #:init-value 0) (chain-progress #:accessor chain-progress #:init-form '()) + (max-chain #:accessor max-chain #:init-value 0) (speed #:accessor speed #:init-value 2.5) (invincible? #:accessor invincible? #:init-value #f) (shooting? #:accessor shooting? #:init-value #f) (shoot-time #:accessor shoot-time #:init-value 0)) +(define-method (dead? (player <player>)) + (zero? (lives player))) + (define (make-player bullet-field) (make <player> #:name 'player #:hitboxes (list graze-hitbox kill-hitbox) - #:position (vec2 80.0 24.0) + #:position (vec2 80.0 -24.0) #:bullet-field bullet-field #:polarity 'white)) @@ -121,11 +132,13 @@ (cond ;; single shot ((zero? t) + (audio-play (asset-ref shoot-sound)) (shoot player 0.0)) ;; double shot. give a buffer of 4 frames so players can ;; reliably fire just a single shot. ((> t 4) - (shoot player 5.0) + (audio-play (asset-ref shoot-sound)) + (shoot player 6.0) (shoot player -5.0)))) (set! (shoot-time player) (+ t 1)))) (next-method)) @@ -188,9 +201,10 @@ (if enemy (let* ((ep (position enemy))) (define (aim-at-enemy bp bv) - (let ((dir (atan (- (vec2-y ep) (vec2-y bp)) - (- (vec2-x ep) (vec2-x bp))))) - (set-vec2! bv (* (cos dir) speed) (* (sin dir) speed)))) + (unless (dead? enemy) + (let ((dir (atan (- (vec2-y ep) (vec2-y bp)) + (- (vec2-x ep) (vec2-x bp))))) + (set-vec2! bv (* (cos dir) speed) (* (sin dir) speed))))) (run-script player (let loop ((i 0)) (when (< i n) @@ -206,6 +220,9 @@ (vec2-x p) (vec2-y p) (* (cos theta) speed) (* (sin theta) speed)) (loop (+ i 1)))))))) + (when (> e 10) + (audio-play (asset-ref missile-sound) + #:volume 0.5)) ;; Distribute missiles amongst closest enemies (let loop ((enemies enemies) (missiles-remaining (quotient e 10)) @@ -229,15 +246,22 @@ (loop enemies 0 (+ missiles-used missiles-remaining))))))) #t)) -(define-method (increment-energy (player <player>)) - (set! (energy player) (min (+ (energy player) 1) 120))) +(define-method (add-energy (player <player>) n) + (set! (energy player) (min (+ (energy player) n) 120))) (define-method (kill-maybe (player <player>)) (unless (invincible? player) - (let ((new-lives (- (lives player) 1))) + (audio-play (asset-ref death-sound)) + (let ((new-lives (max (- (lives player) 1) 0))) (set! (lives player) new-lives) + (set! (energy player) 0) (if (zero? new-lives) - (hide player) + (begin + ;; to stop the death events from happening over and over + ;; after game over condition is reached. + (set! (invincible? player) #t) + (set-vec2! (velocity player) 0.0 0.0) + (hide player)) ;; Give player invincibility for a bit while they recover. (run-script player (set! (invincible? player) #t) @@ -258,7 +282,7 @@ ;; Absorb bullets of the same polarity. ((and (eq? hitbox graze-hitbox) (eq? bullet-polarity (polarity player))) - (increment-energy player) + (add-energy player 1) ;; From what I can tell by watching youtube replays at .25 speed, ;; each bullet absorbed is worth 100 points. (set! (score player) (+ (score player) 100)) @@ -270,13 +294,14 @@ #t) (else #f))) -(define (add-to-chain player polarity) +(define-method (add-to-chain (player <player>) polarity) (let ((current-chain (cons polarity (chain-progress player)))) (match current-chain ;; complete chain. ((or ('white 'white 'white) ('black 'black 'black)) (let ((new-chain (+ (chain player) 1))) + (set! (max-chain player) (max (max-chain player) new-chain)) (set! (chain player) new-chain) (set! (chain-progress player) '()) (set! (score player) |