(define-module (super-bloom actor) #:use-module (catbird asset) #:use-module (catbird node) #:use-module (catbird node-2d) #:use-module (chickadee audio) #:use-module (chickadee data quadtree) #:use-module (chickadee math rect) #:use-module (chickadee math vector) #:use-module (oop goops) #:export ( velocity hitbox world-hitbox quadtree change-velocity direction-to angle-to after-move on-collide refresh-world-hitbox)) (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 (initialize (actor ) initargs) (next-method) (refresh-world-hitbox actor)) (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 (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 (on-exit (actor )) (remove-from-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))) (if (and (= (vec2-x v) 0.0) (= (vec2-y v) 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))) (after-move actor) (refresh-world-hitbox actor) (collision-check actor) (add-to-quadtree actor) (expire-local-matrix actor)))))