From ae60497f7722e01ccceebe799b5820717e048eb3 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Wed, 20 Oct 2021 18:42:10 -0400 Subject: Haven't committed in days, oops! --- bonnie-bee/actor.scm | 89 ++++++++- bonnie-bee/assets.scm | 34 +++- bonnie-bee/background.scm | 105 ++++++++++ bonnie-bee/bullet.scm | 46 ++++- bonnie-bee/common.scm | 7 +- bonnie-bee/flower.scm | 59 ++++-- bonnie-bee/game.scm | 486 +++++++++++++++++++++++++++++++++++++++++----- bonnie-bee/player.scm | 114 +++++++++-- bonnie-bee/popcorn.scm | 39 ++++ bonnie-bee/splash.scm | 2 +- bonnie-bee/turret.scm | 49 +++++ 11 files changed, 946 insertions(+), 84 deletions(-) create mode 100644 bonnie-bee/background.scm create mode 100644 bonnie-bee/popcorn.scm create mode 100644 bonnie-bee/turret.scm (limited to 'bonnie-bee') diff --git a/bonnie-bee/actor.scm b/bonnie-bee/actor.scm index a734d6a..1e21144 100644 --- a/bonnie-bee/actor.scm +++ b/bonnie-bee/actor.scm @@ -1,8 +1,12 @@ (define-module (bonnie-bee actor) + #:use-module (bonnie-bee assets) + #:use-module (bonnie-bee common) + #:use-module (chickadee audio) #:use-module (chickadee data quadtree) #:use-module (chickadee math rect) #:use-module (chickadee math vector) #:use-module (oop goops) + #:use-module (starling asset) #:use-module (starling node) #:use-module (starling node-2d) #:export ( @@ -10,18 +14,45 @@ hitbox world-hitbox quadtree + change-velocity + direction-to + angle-to + after-move on-collide - dead? + out-of-bounds? + + points damage - on-death)) + on-death + + player + bullets + scroll-speed)) (define-class () - (velocity #:getter velocity #:init-form (vec2 0.0 0.0)) + (velocity #:getter velocity #:init-keyword #:velocity #:init-form (vec2 0.0 0.0)) (hitbox #:getter hitbox #:init-keyword #:hitbox) (world-hitbox #:getter world-hitbox #:init-form (make-rect 0.0 0.0 0.0 0.0)) (quadtree #:accessor quadtree #:init-keyword #:quadtree)) +(define-method (change-velocity (actor ) dx dy) + (set-vec2! (velocity actor) dx dy)) + +(define-method (direction-to (actor ) (other )) + (let ((dir (vec2- (position other) (position actor)))) + (vec2-normalize! dir) + dir)) + +(define-method (angle-to (actor ) (other )) + (let ((p1 (position actor)) + (p2 (position other))) + (atan (- (vec2-y p2) (vec2-y p1)) + (- (vec2-x p2) (vec2-x p1))))) + +(define-method (scroll-speed (actor )) + 0.0) + (define-method (add-to-quadtree (actor )) (quadtree-insert! (quadtree actor) (world-hitbox actor) actor)) @@ -38,7 +69,6 @@ (set-rect-height! wh (rect-height h)))) (define-method (on-collide a b) - (pk 'unhandled-collision a b) #f) (define-method (on-enter (actor )) @@ -55,27 +85,66 @@ (rect-intersects? r (world-hitbox other)) (on-collide actor other)))))) +(define-method (after-move (actor )) + #t) + (define-method (update (actor ) dt) (let ((p (position actor)) - (v (velocity actor))) - (if (and (= (vec2-x v) 0.0) (= (vec2-y v) 0.0)) + (v (velocity actor)) + (scroll-speed (scroll-speed actor))) + (if (and (= (vec2-x v) 0.0) + (= (vec2-y v) 0.0) + (= scroll-speed 0.0)) (collision-check actor) (begin (remove-from-quadtree actor) - (vec2-add! p v) + (set-vec2! p + (+ (vec2-x p) (vec2-x v)) + (+ (vec2-y p) (vec2-y v) (- (* scroll-speed dt)))) + (after-move actor) (refresh-world-hitbox actor) (collision-check actor) (add-to-quadtree actor) (dirty! actor))))) +(define-method (dead? (actor )) + #f) + +(define-method (dead? x) + #f) + +(define %bounds + (let ((padding 16.0)) + (make-rect (- padding) + (- padding) + (+ %game-width (* padding 2.0)) + (+ %game-height (* padding 2.0))))) + +(define-method (out-of-bounds? (actor )) + (not (rect-intersects? (world-hitbox actor) %bounds))) + +(define-method (out-of-bounds? x) + #f) + (define-class () - (health #:accessor health #:init-keyword #:health)) + (health #:accessor health #:init-keyword #:health) + (points #:getter points #:init-keyword #:points)) (define-method (dead? (d )) (= (health d) 0)) (define-method (damage (d ) x) - (set! (health d) (max (- (health d) x) 0))) + (set! (health d) (max (- (health d) x) 0)) + (unless (dead? d) + (audio-play (asset-ref enemy-hit-sound) #:volume 0.25))) -(define-method (on-death (d ) bullets) +(define-method (on-death (d )) #t) + +(define-class ()) + +(define-method (scroll-speed (g )) + (scroll-speed (parent g))) + +(define-generic player) +(define-generic bullets) diff --git a/bonnie-bee/assets.scm b/bonnie-bee/assets.scm index 5337215..6b92649 100644 --- a/bonnie-bee/assets.scm +++ b/bonnie-bee/assets.scm @@ -4,15 +4,47 @@ #:use-module (chickadee graphics texture) #:use-module (starling asset) #:export (chonkly-font + monogram-font + background-image + particle-image bee-atlas bullet-atlas - flower-image)) + popcorn-image + flower-image + turret-image + moth-image + explosion-sound + pickup-sound + enemy-shoot-sound + enemy-hit-sound + player-death-sound + player-shoot-sound + player-bomb-sound + pollen-release-sound + intro-music + main-music)) (define (scope-datadir file-name) (let ((prefix (or (getenv "BONNIE_BEE_DATADIR") (getcwd)))) (string-append prefix "/" file-name))) (define-asset chonkly-font (load-font (scope-datadir "assets/fonts/Chonkly.otf") 16)) +(define-asset monogram-font (load-font (scope-datadir "assets/fonts/monogram_extended.ttf") 12)) +(define-asset background-image (load-image (scope-datadir "assets/images/background.png"))) +(define-asset particle-image (load-image (scope-datadir "assets/images/particle.png"))) (define-asset bee-atlas (load-tileset (scope-datadir "assets/images/bee.png") 32 32)) (define-asset bullet-atlas (load-tileset (scope-datadir "assets/images/bullets.png") 16 16)) (define-asset flower-image (load-image (scope-datadir "assets/images/flower.png"))) +(define-asset popcorn-image (load-image (scope-datadir "assets/images/popcorn.png"))) +(define-asset turret-image (load-image (scope-datadir "assets/images/flower-turret.png"))) +(define-asset moth-image (load-image (scope-datadir "assets/images/moth.png"))) +(define-asset explosion-sound (load-audio (scope-datadir "assets/sounds/explosion.wav"))) +(define-asset pickup-sound (load-audio (scope-datadir "assets/sounds/pickup.wav"))) +(define-asset enemy-shoot-sound (load-audio (scope-datadir "assets/sounds/enemy-shoot.wav"))) +(define-asset enemy-hit-sound (load-audio (scope-datadir "assets/sounds/enemy-hit.wav"))) +(define-asset player-death-sound (load-audio (scope-datadir "assets/sounds/player-death.wav"))) +(define-asset player-shoot-sound (load-audio (scope-datadir "assets/sounds/player-shoot.wav"))) +(define-asset player-bomb-sound (load-audio (scope-datadir "assets/sounds/player-bomb.wav"))) +(define-asset pollen-release-sound (load-audio (scope-datadir "assets/sounds/pollen-release.wav"))) +(define-asset intro-music (load-audio (scope-datadir "assets/sounds/intro.wav") #:mode 'stream)) +(define-asset main-music (load-audio (scope-datadir "assets/sounds/main.wav") #:mode 'stream)) diff --git a/bonnie-bee/background.scm b/bonnie-bee/background.scm new file mode 100644 index 0000000..f374556 --- /dev/null +++ b/bonnie-bee/background.scm @@ -0,0 +1,105 @@ +(define-module (bonnie-bee background) + #:use-module (bonnie-bee assets) + #:use-module (bonnie-bee common) + #:use-module (chickadee graphics buffer) + #:use-module (chickadee graphics engine) + #:use-module (chickadee graphics shader) + #:use-module (chickadee graphics texture) + #:use-module (chickadee math) + #:use-module (chickadee math matrix) + #:use-module (chickadee math vector) + #:use-module (chickadee scripting) + #:use-module (chickadee utils) + #:use-module (oop goops) + #:use-module (starling node) + #:use-module (starling node-2d) + #:export ( + scroll-y)) + +(define (make-background-shader) + (strings->shader + " +#ifdef GLSL330 +layout (location = 0) in vec2 position; +layout (location = 1) in vec2 tex; +#elif defined(GLSL130) +in vec2 position; +in vec2 tex; +#elif defined(GLSL120) +attribute vec2 position; +attribute vec2 tex; +#endif +#ifdef GLSL120 +varying vec2 fragTex; +#else +out vec2 fragTex; +#endif +uniform mat4 mvp; + +void main(void) { + fragTex = tex; + gl_Position = mvp * vec4(position.xy, 0.0, 1.0); +} +" + " +#ifdef GLSL120 +varying vec2 fragTex; +#else +in vec2 fragTex; +#endif +#ifdef GLSL330 +out vec4 fragColor; +#else +#define fragColor gl_FragColor +#endif +uniform sampler2D image; +uniform float scrollY; + +void main (void) { + vec2 uv = vec2(fragTex.x, fragTex.y + scrollY); + fragColor = texture(image, uv); +} +")) + +(define-geometry-type + background-vertex-ref + background-vertex-set! + background-vertex-append! + (position vec2) + (texture vec2)) + +(define (make-background-geometry) + (let* ((g (make-geometry 4 #:index-capacity 6)) + (x1 0.0) + (y1 0.0) + (x2 (exact->inexact %game-width)) + (y2 (exact->inexact %game-height)) + (s1 0.0) + (t1 0.0) + (s2 1.0) + (t2 1.0)) + (with-geometry g + (background-vertex-append! g + (x1 y1 s1 t1) + (x2 y1 s2 t1) + (x2 y2 s2 t2) + (x1 y2 s1 t2)) + (geometry-index-append! g 0 3 2 0 2 1)) + g)) + +(define-class () + (scroll-y #:accessor scroll-y #:init-value 0.0) + (texture #:accessor texture #:init-keyword #:texture #:asset? #t) + (shader #:getter shader #:init-thunk make-background-shader) + (geometry #:getter geometry #:init-thunk make-background-geometry) + (mvp-matrix #:getter mvp-matrix #:init-thunk make-identity-matrix4)) + +(define-method (render (background ) alpha) + (let ((mvp (mvp-matrix background)) + (t (texture background))) + (matrix4-mult! mvp (world-matrix background) (current-projection)) + (with-graphics-state ((g:texture-0 t)) + (shader-apply (shader background) + (geometry-vertex-array (geometry background)) + #:scroll-y (/ (scroll-y background) (texture-height t)) + #:mvp mvp)))) diff --git a/bonnie-bee/bullet.scm b/bonnie-bee/bullet.scm index 0fb351b..2cd722b 100644 --- a/bonnie-bee/bullet.scm +++ b/bonnie-bee/bullet.scm @@ -14,10 +14,18 @@ #:use-module (starling node) #:use-module (starling node-2d) #:export ( - name + player-bullet? + player-primary-bullet? + player-bomb-bullet? + enemy-bullet? player-primary-bullet + player-bomb-bullet + large-enemy-bullet + medium-enemy-bullet + small-enemy-bullet pollen-pickup + clear-bullets type kill-bullet @@ -36,6 +44,22 @@ (make #:name 'player-primary #:atlas-index 4 #:hitbox (make-rect -7.0 -7.0 14.0 14.0))) +(define player-bomb-bullet + (make #:name 'player-bomb #:atlas-index 5 + #:hitbox (make-rect -4.0 -4.0 8.0 8.0))) + +(define large-enemy-bullet + (make #:name 'large-enemy #:atlas-index 0 + #:hitbox (make-rect -4.0 -4.0 8.0 8.0))) + +(define medium-enemy-bullet + (make #:name 'medium-enemy #:atlas-index 1 + #:hitbox (make-rect -2.0 -2.0 4.0 4.0))) + +(define small-enemy-bullet + (make #:name 'small-enemy #:atlas-index 2 + #:hitbox (make-rect -0.5 -0.5 1.0 1.0))) + ;; Yeah... pollen is a bullet. Didn't you know that?? (define pollen-pickup (make #:name 'pollen #:atlas-index 6 @@ -80,6 +104,9 @@ (set! (hitboxes bullets) (make-vector* %max-bullets make-null-rect)) (set! (regions bullets) (make-vector* %max-bullets make-null-rect))) +(define-method (clear-bullets (bullets )) + (set! (size bullets) 0)) + (define-class () (parent #:getter parent #:init-keyword #:parent) (type #:accessor type) @@ -189,3 +216,20 @@ (set-rect-y! h (+ (rect-y h) (vec2-y v))) (quadtree-insert! q h d) (loop (+ i 1))))))))) + +(define (player-bullet? bullet) + (let ((t (type bullet))) + (or (eq? t player-primary-bullet) + (eq? t player-bomb-bullet)))) + +(define (player-primary-bullet? bullet) + (eq? (type bullet) player-primary-bullet)) + +(define (player-bomb-bullet? bullet) + (eq? (type bullet) player-bomb-bullet)) + +(define (enemy-bullet? bullet) + (let ((t (type bullet))) + (or (eq? t small-enemy-bullet) + (eq? t medium-enemy-bullet) + (eq? t large-enemy-bullet)))) diff --git a/bonnie-bee/common.scm b/bonnie-bee/common.scm index fa9f14a..75a6bc4 100644 --- a/bonnie-bee/common.scm +++ b/bonnie-bee/common.scm @@ -1,4 +1,5 @@ (define-module (bonnie-bee common) + #:use-module (chickadee game-loop) #:use-module (chickadee graphics color) #:use-module (chickadee graphics viewport) #:use-module (chickadee math vector) @@ -9,7 +10,8 @@ %window-height %game-width %game-height - set-cameras!)) + set-cameras! + steps)) (define %window-width 960) (define %window-height 720) @@ -22,3 +24,6 @@ #:resolution (vec2 %game-width %game-height) #:viewport (make-viewport 0 0 %window-width %window-height #:clear-color black))))) + +(define (steps n) + (* n (current-timestep))) diff --git a/bonnie-bee/flower.scm b/bonnie-bee/flower.scm index cafa4f8..2c018e9 100644 --- a/bonnie-bee/flower.scm +++ b/bonnie-bee/flower.scm @@ -2,16 +2,33 @@ #:use-module (bonnie-bee actor) #:use-module (bonnie-bee assets) #:use-module (bonnie-bee bullet) + #:use-module (chickadee audio) + #:use-module (chickadee graphics particles) #:use-module (chickadee math) + #:use-module (chickadee math rect) #:use-module (chickadee math vector) #:use-module (chickadee scripting) #:use-module (chickadee utils) #:use-module (oop goops) + #:use-module (starling asset) #:use-module (starling node) #:use-module (starling node-2d) - #:export ()) + #:export ( + pollen-enabled? + enable-pollen! + disable-pollen!)) -(define-class ( )) +(define-class ( ) + (emit-pollen? #:allocation #:class #:init-value #f)) + +(define (pollen-enabled?) + (class-slot-ref 'emit-pollen?)) + +(define (enable-pollen!) + (class-slot-set! 'emit-pollen? #t)) + +(define (disable-pollen!) + (class-slot-set! 'emit-pollen? #f)) (define-method (on-boot (flower )) (attach-to flower @@ -20,18 +37,30 @@ #:origin (vec2 32.0 32.0)))) (define-method (on-collide (flower ) (bullet )) - (if (eq? (type bullet) player-primary-bullet) - (begin - (damage flower 1) - (kill-bullet bullet) - #t) - #f)) + (cond + ((player-bullet? bullet) + (damage flower 1) + (kill-bullet bullet) + #t) + ((and (not (pollen-enabled?)) (enemy-bullet? bullet)) + (damage flower 1000) + (kill-bullet bullet)) + (else #f))) -(define-method (on-death (flower ) bullets) +(define-method (on-death (flower )) (let ((p (position flower))) - (for-range ((i 16)) - (let ((theta (- (* (random:uniform) (/ pi -2.0)) (/ pi 4.0))) - (speed (+ (* (random:uniform) 1.0) 1.0))) - (add-bullet bullets pollen-pickup p - (vec2 (* (cos theta) speed) - (* (sin theta) speed))))))) + (if (pollen-enabled?) + (begin + (audio-play (asset-ref pollen-release-sound)) + (for-range ((i 16)) + (let ((theta (- (* (random:uniform) (/ pi -2.0)) (/ pi 4.0))) + (speed (+ (* (random:uniform) 1.0) 1.0))) + (add-bullet (bullets (parent flower)) + pollen-pickup p + (vec2 (* (cos theta) speed) + (* (sin theta) speed)))))) + (begin + (audio-play (asset-ref explosion-sound)) + (add-particle-emitter (particles (particles (parent flower))) + (make-particle-emitter (make-rect (vec2-x p) (vec2-y p) 1.0 1.0) + 10 5)))))) diff --git a/bonnie-bee/game.scm b/bonnie-bee/game.scm index ad1d9c3..ffdbc3e 100644 --- a/bonnie-bee/game.scm +++ b/bonnie-bee/game.scm @@ -1,16 +1,23 @@ (define-module (bonnie-bee game) #:use-module (bonnie-bee actor) #:use-module (bonnie-bee assets) + #:use-module (bonnie-bee background) #:use-module (bonnie-bee bullet) #:use-module (bonnie-bee common) #:use-module (bonnie-bee flower) #:use-module (bonnie-bee player) + #:use-module (bonnie-bee turret) + #:use-module (bonnie-bee popcorn) + #:use-module (chickadee) + #:use-module (chickadee audio) #:use-module (chickadee data quadtree) #:use-module (chickadee graphics color) + #:use-module (chickadee graphics particles) #:use-module (chickadee math rect) #:use-module (chickadee math vector) #:use-module (chickadee scripting) #:use-module (oop goops) + #:use-module (starling asset) #:use-module (starling kernel) #:use-module (starling node) #:use-module (starling node-2d) @@ -20,10 +27,20 @@ (define %game-bounds (make-rect 0.0 0.0 %game-width %game-height)) (define-class () - (quadtree #:getter quadtree #:init-form (make-quadtree %game-bounds))) + (state #:accessor state #:init-value 'play) + (quadtree #:getter quadtree #:init-form (make-quadtree %game-bounds)) + (scroll-speed #:getter scroll-speed #:init-value 0.0) + (last-lives #:accessor last-lives #:init-value 0) + (last-pollen #:accessor last-pollen #:init-value 0) + (last-score #:accessor last-score #:init-value 0) + (music-source #:getter music-source #:init-form (make-source #:loop? #t))) + +(define-method (change-scroll-speed (game ) speed) + (slot-set! game 'scroll-speed speed)) (define-method (spawn (game ) (actor )) (set! (quadtree actor) (quadtree game)) + (quadtree-insert! (quadtree game) (world-hitbox actor) actor) (attach-to game actor)) (define-method (player (game )) @@ -32,64 +49,445 @@ (define-method (bullets (game )) (& game bullets)) +(define-method (particles (game )) + (& game particles)) + (define-method (on-boot (game )) (set! *random-state* (random-state-from-platform)) (set-cameras! game) (attach-to game + (make + #:name 'background + #:texture background-image) + (make + #:name 'particles + #:particles (make-particles 2048 #:texture (asset-ref particle-image))) (make #:name 'bullets - #:quadtree (quadtree game)))) + #:rank 3 + #:quadtree (quadtree game)) + (make