summaryrefslogtreecommitdiff
path: root/lisparuga/player.scm
diff options
context:
space:
mode:
Diffstat (limited to 'lisparuga/player.scm')
-rw-r--r--lisparuga/player.scm51
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)