summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2023-10-29 18:53:13 -0400
committerDavid Thompson <dthompson2@worcester.edu>2023-10-29 20:34:03 -0400
commitf50e0e1fe5daa7e136b85a967642d32b5e9d9240 (patch)
tree24a8e02d00754aa4bd48bd36c5966b86f8c808a9
parentc912690c7652f10c4dc560935cc197552b16356c (diff)
Boss fight!
-rw-r--r--game.scm181
-rw-r--r--images/boss.asebin2032 -> 12501 bytes
-rw-r--r--images/boss.pngbin2354 -> 8814 bytes
-rw-r--r--level.tmx2
-rw-r--r--todo.org6
5 files changed, 183 insertions, 6 deletions
diff --git a/game.scm b/game.scm
index d33ea54..13e5bc8 100644
--- a/game.scm
+++ b/game.scm
@@ -945,6 +945,7 @@
(when (eq? (enemy-type enemy) 'boss)
(run-script
(lambda ()
+ (set! *player-invincible?* #t)
(wait 60)
(do-game-clear))))
(enemy-pool-remove! pool i)
@@ -1195,10 +1196,180 @@
(spawn-flyer1* x (+ y game-height 8.0) script))
(define (spawn-boss x y)
+ (define (script boss)
+ (define (muzzle-flash x y)
+ (let ((life 6)
+ (ldx -1.0)
+ (rdx 1.0)
+ (dy 1.0))
+ (particle-pool-add! particles 'muzzle-flash life x y ldx dy)
+ (particle-pool-add! particles 'muzzle-flash life x y rdx dy)))
+ (define (shoot x y dx dy)
+ (bullet-pool-add! enemy-bullets 0 x y 2.0 2.0 dx dy))
+ (define (xoff dx)
+ (+ (enemy-x boss) dx))
+ (define (yoff dy)
+ (+ (enemy-y boss) dy))
+ (define (shoot+flash xo yo dx dy)
+ (let ((x (xoff xo))
+ (y (yoff yo)))
+ (shoot x y dx dy)
+ (muzzle-flash x y)))
+ (define main-left-x -43.0)
+ (define main-right-x 43.0)
+ (define main-y 48.0)
+ (define alt-left-x -58.0)
+ (define alt-right-x 58.0)
+ (define alt-y 28.0)
+ (define (shoot-main-left dx dy)
+ (shoot+flash main-left-x main-y dx dy))
+ (define (shoot-main-right dx dy)
+ (shoot+flash main-right-x main-y dx dy))
+ (define (shoot-alt-left dx dy)
+ (shoot+flash alt-left-x alt-y dx dy))
+ (define (shoot-alt-right dx dy)
+ (shoot+flash alt-right-x alt-y dx dy))
+ (define (player-dir dx dy)
+ (let ((p (enemy-position boss)))
+ (direction-to-player
+ (vec2 (+ (vec2-x p) dx) (+ (vec2-y p) dy)))))
+ (define (wait-if duration pred consequent alternate)
+ (let loop ((d duration))
+ (if (= d 0)
+ (consequent)
+ (begin
+ (wait 1)
+ (if (pred)
+ (loop (- d 1))
+ (alternate))))))
+ (define (nop) #f)
+ ;; alt guns make Xs across the screen
+ ;; main guns shoot at player
+ ;; beak shoots spiral
+ (define (phase-2)
+ (define (pred) (> (enemy-health boss) 500))
+ (wait 180)
+ (run-script
+ (lambda ()
+ (let loop ()
+ (let ((dx 2.0)
+ (dy 4.0))
+ (do ((i 0 (+ i 1)))
+ ((= i 30))
+ (shoot-alt-left dx dy)
+ (shoot-alt-right (- dx) dy)
+ (wait 4))
+ (wait-if 60 pred loop nop)))))
+ (run-script
+ (lambda ()
+ (wait 120)
+ (let loop ()
+ (let ((v (player-dir main-left-x main-y)))
+ (vec2-mul-scalar! v 3.5)
+ (do ((i 0 (+ i 1)))
+ ((= i 5))
+ (shoot-alt-left (vec2-x v) (vec2-y v))
+ (wait 4)))
+ (wait-if 120 pred loop nop))))
+ (run-script
+ (lambda ()
+ (wait 60)
+ (let loop ()
+ (let ((v (player-dir main-right-x main-y)))
+ (vec2-mul-scalar! v 3.5)
+ (do ((i 0 (+ i 1)))
+ ((= i 5))
+ (shoot-alt-right (vec2-x v) (vec2-y v))
+ (wait 4)))
+ (wait-if 120 pred loop nop))))
+ (let ((x (enemy-x boss))
+ (y (+ (enemy-y boss) 48.0))
+ (speed 0.75))
+ (let loop ((offset 0.0))
+ (do-circle
+ (lambda (theta)
+ (let ((theta* (+ theta offset)))
+ (shoot x y (* (cos theta*) speed) (* (sin theta*) speed))))
+ 3)
+ (wait-if 10 pred (lambda () (loop (+ offset 0.3))) phase-3))))
+ ;; intense alt fire aimed at player
+ ;; half-circle arcs of bullets at player
+ (define (phase-3)
+ (define (pred) #t)
+ (wait 180)
+ (run-script
+ (lambda ()
+ (wait 120)
+ (let outer ()
+ (let ((v (player-dir alt-left-x alt-y)))
+ (vec2-mul-scalar! v 3.5)
+ (let inner ((i 0))
+ (when (< i 15)
+ (shoot-alt-left (vec2-x v) (vec2-y v))
+ (wait 4)
+ (inner (+ i 1))))
+ (wait-if 10 pred outer nop)))))
+ (run-script
+ (lambda ()
+ (wait 60)
+ (let outer ()
+ (let ((v (player-dir alt-right-x alt-y)))
+ (vec2-mul-scalar! v 3.5)
+ (let inner ((i 0))
+ (when (< i 15)
+ (shoot-alt-right (vec2-x v) (vec2-y v))
+ (wait 4)
+ (inner (+ i 1))))
+ (wait-if 10 pred outer nop)))))
+ (let ((speed 1.0)
+ (k 10))
+ (let outer ()
+ (let inner ((i 0))
+ (when (<= i k)
+ (let ((theta (* (inexact (/ i k)) pi)))
+ (shoot-main-left (* (cos theta) speed) (* (sin theta) speed))
+ (shoot-main-right (* (cos theta) speed) (* (sin theta) speed))
+ (inner (+ i 1)))))
+ (wait-if 60 pred outer nop))))
+ ;; alt guns fired aimed shots at player
+ ;; main guns shoot spirals
+ (define (phase-1)
+ (define (pred) (> (enemy-health boss) 1000))
+ (run-script
+ (lambda ()
+ (wait 120)
+ (let loop ()
+ (let ((v (player-dir alt-left-x alt-y)))
+ (vec2-mul-scalar! v 3.5)
+ (do ((i 0 (+ i 1)))
+ ((= i 5))
+ (shoot-alt-left (vec2-x v) (vec2-y v))
+ (wait 4)))
+ (wait-if 120 pred loop nop))))
+ (run-script
+ (lambda ()
+ (wait 60)
+ (let loop ()
+ (let ((v (player-dir alt-right-x alt-y)))
+ (vec2-mul-scalar! v 3.5)
+ (do ((i 0 (+ i 1)))
+ ((= i 5))
+ (shoot-alt-right (vec2-x v) (vec2-y v))
+ (wait 4)))
+ (wait-if 120 pred loop nop))))
+ (let ((speed 0.75))
+ (let loop ((theta 0.0))
+ (let ((dx (* (cos theta) speed))
+ (dy (* (sin theta) speed)))
+ (shoot-main-left dx dy)
+ (shoot-main-right (- dx) dy)
+ (wait-if 5 pred (lambda () (loop (+ theta 0.4))) phase-2)))))
+ (wait 180)
+ (phase-1))
(spawn-enemy
- (make-enemy 'boss 300 (vec2 x (- y 24.0)) (vec2 144.0 50.0)
- (vec2 0.0 0.0) #f 500000
- #(0.0 0.0 0.0 0.0) image:boss (vec2 144.0 96.0))))
+ (make-enemy 'boss 1500 (vec2 x (- y 24.0)) (vec2 144.0 50.0)
+ (vec2 0.0 0.0) script 500000
+ #(0.0 144.0 288.0 432.0) image:boss (vec2 144.0 96.0))))
;; Player state:
(define player-position (vec2 (/ game-width 2.0) (- game-height 12.0)))
@@ -1627,11 +1798,11 @@
(set! *game-state* 'play)
(scheduler-reset! *scheduler*)
(set! *scroll* 0.0)
- ;; (set! *scroll* (* 60.0 tile-height))
+ ;; (set! *scroll* (* 440.0 tile-height))
(set! *last-scroll* 0.0)
(set! *last-row-scanned* (level-height level))
;; (set! *last-row-scanned* (- (level-height level)
- ;; 60))
+ ;; 440))
(bullet-pool-reset! player-bullets)
(bullet-pool-reset! enemy-bullets)
(enemy-pool-reset! enemies)
diff --git a/images/boss.ase b/images/boss.ase
index 70b2ee5..75e27a3 100644
--- a/images/boss.ase
+++ b/images/boss.ase
Binary files differ
diff --git a/images/boss.png b/images/boss.png
index 0b1ab82..cc740ee 100644
--- a/images/boss.png
+++ b/images/boss.png
Binary files differ
diff --git a/level.tmx b/level.tmx
index 288bf3f..69a501e 100644
--- a/level.tmx
+++ b/level.tmx
@@ -1047,7 +1047,7 @@
<object id="162" type="boss" x="112" y="64" width="16" height="16"/>
<object id="163" type="scroll-speed" x="0" y="0" width="16" height="16">
<properties>
- <property name="duration" type="int" value="30"/>
+ <property name="duration" type="int" value="45"/>
<property name="speed" type="float" value="0"/>
</properties>
</object>
diff --git a/todo.org b/todo.org
index e135b11..5b403b0 100644
--- a/todo.org
+++ b/todo.org
@@ -40,5 +40,11 @@
- scrolling stops, boss appears
- boss goes through 2-3 phases of bullet patterns as its health drops
* TODO music track
+G# minor
+
+B D# G# B D#
+
+E G# B G# D# G# B G# -- loop D G# B G#
+
* DONE particles
* TODO juice!