(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 (catbird asset) #:use-module (catbird node) #:use-module (catbird node-2d) #:use-module (catbird scene) #:export ( velocity hitbox world-hitbox quadtree change-velocity direction-to angle-to after-move on-collide dead? out-of-bounds? health points damage on-death player bullets scroll-speed spawn)) (define-class () (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)) (define-method (remove-from-quadtree (actor )) (quadtree-delete! (quadtree actor) (world-hitbox actor) actor)) (define-method (refresh-world-hitbox (actor )) (let ((p (position actor)) (h (hitbox actor)) (wh (world-hitbox actor))) (set-rect-x! wh (+ (vec2-x p) (rect-x h))) (set-rect-y! wh (+ (vec2-y p) (rect-y h))) (set-rect-width! wh (rect-width h)) (set-rect-height! wh (rect-height h)))) (define-method (on-collide a b) #f) (define-method (on-enter (actor )) (refresh-world-hitbox actor) (add-to-quadtree actor)) (define-method (collision-check (actor )) (let ((p (position actor)) (r (world-hitbox actor))) (quadtree-find (quadtree actor) r (lambda (other) (and (not (eq? other actor)) (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)) (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) (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) (expire-local-matrix 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) (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)) (unless (dead? d) (audio-play (artifact enemy-hit-sound) #:volume 0.25))) (define-method (on-death (d )) #t) (define-class ()) (define-method (scroll-speed (g )) (scroll-speed (parent g))) (define-generic player) (define-generic bullets) (define-generic spawn)