From e641e20d037b7a135b7bea19e205660f1426d3cf Mon Sep 17 00:00:00 2001 From: David Thompson Date: Thu, 26 Oct 2023 08:00:44 -0400 Subject: Per-bullet hitboxes; scoring. --- game.scm | 113 +++++++++++++++++++++++++++------------------- images/player-bullets.ase | Bin 523 -> 523 bytes images/player-bullets.png | Bin 175 -> 194 bytes 3 files changed, 66 insertions(+), 47 deletions(-) diff --git a/game.scm b/game.scm index cf72933..25a4986 100644 --- a/game.scm +++ b/game.scm @@ -396,27 +396,33 @@ bullet-pool? (length bullet-pool-length set-bullet-pool-length!) (capacity bullet-pool-capacity set-bullet-pool-capacity!) + (image bullet-pool-image set-bullet-pool-image!) (bullets bullet-pool-bullets set-bullet-pool-bullets!)) - ;; per bullet: type, x, y, dx, dy - (define %bullet-size (+ 4 8 8 8 8)) - (define (make-bullet-pool capacity) + (define bullet-tile-width 16.0) + (define bullet-tile-height 16.0) + ;; per bullet: type, tile-x, x, y, w, h, dx, dy + (define %bullet-size (+ 4 8 8 8 8 8 8 8)) + (define (make-bullet-pool capacity image) (let ((bullets (make-bytevector (* capacity %bullet-size)))) - (%make-bullet-pool 0 capacity bullets))) + (%make-bullet-pool 0 capacity image bullets))) (define (bullet-pool-offset i) (* i %bullet-size)) - (define (bullet-pool-add! pool type x y dx dy) + (define (bullet-pool-add! pool type x y w h dx dy) (match pool - (#('bullet-pool length capacity bullets) + (#('bullet-pool length capacity image bullets) (let ((offset (bullet-pool-offset length))) (s32-set! bullets offset type) - (f64-set! bullets (+ offset 4) x) - (f64-set! bullets (+ offset 12) y) - (f64-set! bullets (+ offset 20) dx) - (f64-set! bullets (+ offset 28) dy) + (f64-set! bullets (+ offset 4) (* type bullet-tile-width)) + (f64-set! bullets (+ offset 12) x) + (f64-set! bullets (+ offset 20) y) + (f64-set! bullets (+ offset 28) w) + (f64-set! bullets (+ offset 36) h) + (f64-set! bullets (+ offset 44) dx) + (f64-set! bullets (+ offset 52) dy) (set-bullet-pool-length! pool (+ length 1)))))) (define (bullet-pool-remove! pool i) (match pool - (#('bullet-pool length capacity bullets) + (#('bullet-pool length capacity image bullets) (when (and (>= i 0) (< i length)) (let ((at (bullet-pool-offset i)) (start (bullet-pool-offset (- length 1)))) @@ -426,39 +432,45 @@ (set-bullet-pool-length! pool 0)) (define (bullet-pool-update! pool collide) (match pool - (#('bullet-pool length capacity bullets) + (#('bullet-pool length capacity image bullets) (let loop ((i 0) (k length)) (when (< i k) (let* ((offset (bullet-pool-offset i)) - (x (f64-ref bullets (+ offset 4))) - (y (f64-ref bullets (+ offset 12))) - (dx (f64-ref bullets (+ offset 20))) - (dy (f64-ref bullets (+ offset 28))) + (x (f64-ref bullets (+ offset 12))) + (y (f64-ref bullets (+ offset 20))) + (w (f64-ref bullets (+ offset 28))) + (h (f64-ref bullets (+ offset 36))) + (dx (f64-ref bullets (+ offset 44))) + (dy (f64-ref bullets (+ offset 52))) (x* (+ x dx)) (y* (+ y dy))) (cond - ;; TODO: different bullet hitbox sizes. - ((collide x y 2.0 2.0) + ((collide x* y* w h) (bullet-pool-remove! pool i) (loop i (- k 1))) (else - (f64-set! bullets (+ offset 4) x*) - (f64-set! bullets (+ offset 12) y*) + (f64-set! bullets (+ offset 12) x*) + (f64-set! bullets (+ offset 20) y*) (loop (+ i 1) k))))))))) - (define (draw-bullets pool image w h) + (define (draw-bullets pool) (match pool - (#('bullet-pool length capacity bullets) + (#('bullet-pool length capacity image bullets) (do ((i 0 (+ i 1))) ((= i length)) (let* ((offset (bullet-pool-offset i)) - (type (s32-ref bullets offset)) - (x (f64-ref bullets (+ offset 4))) - (y (f64-ref bullets (+ offset 12)))) - (draw-image context image (* type w) 0.0 w h - (- x (/ w 2.0)) (- y (/ w 2.0)) w h)))))) + (tx (f64-ref bullets (+ offset 4))) + (x (f64-ref bullets (+ offset 12))) + (y (f64-ref bullets (+ offset 20))) + (w (f64-ref bullets (+ offset 28))) + (h (f64-ref bullets (+ offset 36)))) + (draw-image context image (pk tx) 0.0 + bullet-tile-width bullet-tile-height + (- x (/ bullet-tile-width 2.0)) + (- y (/ bullet-tile-height 2.0)) + bullet-tile-width bullet-tile-height)))))) - (define player-bullets (make-bullet-pool 200)) - (define enemy-bullets (make-bullet-pool 400)) + (define player-bullets (make-bullet-pool 200 image:player-bullets)) + (define enemy-bullets (make-bullet-pool 400 image:enemy-bullets)) ;; Scrolling level: (define *scroll* 0.0) @@ -578,7 +590,8 @@ (size enemy-size set-enemy-size!) (stationary? enemy-stationary? set-enemy-stationary!) (velocity enemy-velocity set-enemy-velocity!) - (script enemy-script set-enemy-script!)) + (script enemy-script set-enemy-script!) + (points enemy-points set-enemy-points!)) (define (enemy-x enemy) (vec2-x (enemy-position enemy))) (define (enemy-y enemy) @@ -593,18 +606,18 @@ (vec2-y (enemy-velocity enemy))) (define (enemy-damage! enemy damage) (match enemy - (#('enemy type health _ _ _ _ _) + (#('enemy type health _ _ _ _ _ _) (set-enemy-health! enemy (- health damage))))) (define (enemy-dead? enemy) (<= (enemy-health enemy) 0)) (define (enemy-out-of-bounds? enemy) (match enemy - (#('enemy _ _ position size _ _ _) + (#('enemy _ _ position size _ _ _ _) (out-of-bounds? (vec2-x position) (vec2-y position) (vec2-x size) (vec2-y size))))) (define (enemy-within-rect? enemy x y w h) (match enemy - (#('enemy _ _ position size _ _ _) + (#('enemy _ _ position size _ _ _ _) (let* ((w* (vec2-x size)) (h* (vec2-y size)) (x* (- (vec2-x position) (/ w* 2.0))) @@ -620,7 +633,7 @@ (script-cancel! script)))) (define (enemy-update! enemy) (match enemy - (#('enemy _ _ position size stationary? velocity _) + (#('enemy _ _ position size stationary? velocity _ _) (if stationary? (set-vec2-y! position (+ (vec2-y position) (- *scroll* *last-scroll*))) (begin @@ -628,7 +641,7 @@ (set-vec2-y! position (+ (vec2-y position) (vec2-y velocity)))))))) (define (enemy-draw enemy) (match enemy - (#('enemy type _ position size _ _ _) + (#('enemy type _ position size _ _ _ _) (let* ((t 0.0) (x (vec2-x position)) (y (vec2-y position)) @@ -689,7 +702,9 @@ ((or (enemy-dead? enemy) (enemy-out-of-bounds? enemy)) (when (enemy-dead? enemy) - (sound-effect-play sound:explosion)) + (sound-effect-play sound:explosion) + (set! *player-score* + (+ *player-score* (enemy-points enemy)))) (enemy-pool-remove! pool i) (loop i (- k 1))) (else @@ -723,12 +738,13 @@ (bullet-pool-add! enemy-bullets 0 (enemy-x enemy) (enemy-y enemy) + 2.0 2.0 (* (vec2-x v) speed) (* (vec2-y v) speed))) (wait 30) (loop (+ theta 0.2))))) (let ((enemy (make-enemy 'foo 20 (vec2 x y) (vec2 16.0 16.0) - #t (vec2 0.0 0.0) script))) + #t (vec2 0.0 0.0) script 100))) (enemy-pool-add! enemies enemy))) ;; Player state: @@ -749,6 +765,7 @@ (define *player-lives* %default-lives) (define *player-visible?* #t) (define *player-invincible?* #f) + (define *player-score* 0) ;; left, right, down, up, fire, focus (define key-state (vector #f #f #f #f #f #f)) (define (update-player-velocity!) @@ -838,15 +855,18 @@ (bullet-pool-add! player-bullets 1 (vec2-x player-position) (vec2-y player-position) + 6.0 6.0 0.0 (- player-bullet-speed)) (begin (bullet-pool-add! player-bullets 0 (- (vec2-x player-position) 6.0) (vec2-y player-position) + 3.0 4.0 0.0 (- player-bullet-speed)) (bullet-pool-add! player-bullets 0 (+ (vec2-x player-position) 8.0) (vec2-y player-position) + 3.0 4.0 0.0 (- player-bullet-speed)))) (set! *player-fire-counter* 0)))) (define (draw-player) @@ -894,10 +914,10 @@ (clear-rect context 0.0 0.0 *canvas-width* *canvas-height*)) (define (draw-player-bullets) - (draw-bullets player-bullets image:player-bullets 8.0 8.0)) + (draw-bullets player-bullets)) (define (draw-enemy-bullets) - (draw-bullets enemy-bullets image:enemy-bullets 16.0 16.0)) + (draw-bullets enemy-bullets)) (define (draw-background image parallax) (let ((scroll (remainder (* *scroll* parallax) game-height))) @@ -915,14 +935,12 @@ ;; TODO: Don't strings every frame when the UI values rarely ;; change. (set-fill-color! context "#ffffff") - (set-font! context "bold 8px monospace") + (set-font! context "bold 16px monospace") (set-text-align! context "right") (fill-text context (string-append "x" (number->string *player-lives*)) (- game-width 4.0) y) - ;; TODO: Add scoring. (set-text-align! context "left") - (fill-text context (string-append "score " (number->string 0)) - 4.0 y))) + (fill-text context (number->string *player-score*) 4.0 y))) (define (draw time) (clear-screen) @@ -941,17 +959,17 @@ (match *game-state* ('game-over (set-fill-color! context "#ffffff") - (set-font! context "bold 24px monospace") + (set-font! context "bold 36px monospace") (set-text-align! context "center") (fill-text context "GAME OVER" (/ game-width 2.0) (/ game-height 2.0))) ('game-win (set-fill-color! context "#ffffff") - (set-font! context "bold 24px monospace") + (set-font! context "bold 36px monospace") (set-text-align! context "center") (fill-text context "WELL DONE" (/ game-width 2.0) (/ game-height 2.0))) ('paused (set-fill-color! context "#ffffff") - (set-font! context "bold 24px monospace") + (set-font! context "bold 36px monospace") (set-text-align! context "center") (fill-text context "PAUSED" (/ game-width 2.0) (/ game-height 2.0))) (_ #t)) @@ -971,7 +989,8 @@ (set! *player-lives* %default-lives) (set! *player-invincible?* #f) (set! *player-visible?* #t) - (set! *player-fire-counter* 0)) + (set! *player-fire-counter* 0) + (set! *player-score* 0)) (define (on-key-down event) (let ((code (keyboard-event-code event))) diff --git a/images/player-bullets.ase b/images/player-bullets.ase index 354b729..ddb62c3 100644 Binary files a/images/player-bullets.ase and b/images/player-bullets.ase differ diff --git a/images/player-bullets.png b/images/player-bullets.png index 7c80630..ef1e432 100644 Binary files a/images/player-bullets.png and b/images/player-bullets.png differ -- cgit v1.2.3