From f50e0e1fe5daa7e136b85a967642d32b5e9d9240 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Sun, 29 Oct 2023 18:53:13 -0400 Subject: Boss fight! --- game.scm | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- images/boss.ase | Bin 2032 -> 12501 bytes images/boss.png | Bin 2354 -> 8814 bytes level.tmx | 2 +- todo.org | 6 ++ 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 Binary files a/images/boss.ase and b/images/boss.ase differ diff --git a/images/boss.png b/images/boss.png index 0b1ab82..cc740ee 100644 Binary files a/images/boss.png and b/images/boss.png differ diff --git a/level.tmx b/level.tmx index 288bf3f..69a501e 100644 --- a/level.tmx +++ b/level.tmx @@ -1047,7 +1047,7 @@ - + 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! -- cgit v1.2.3