From a7bb98983c8e80cee47853e5f747fb4d838dd7a2 Mon Sep 17 00:00:00 2001 From: Jeremy Penner Date: Sat, 28 Oct 2023 00:19:39 -0400 Subject: [PATCH] collision detection, remove cleanup in favour of reverse iteration --- src/explosion.fnl | 51 +++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/explosion.fnl b/src/explosion.fnl index f76046a..d3c6fda 100644 --- a/src/explosion.fnl +++ b/src/explosion.fnl @@ -10,7 +10,6 @@ (local draw (defmulti #$1)) (local update (defmulti #$1)) (local children (defmulti #$2)) -(local cleanup (defmulti #$1)) (local scene (defmulti #$1)) (fn destroy-all [type ctx] (cache.destroy type) (tset ctx type nil)) @@ -27,7 +26,6 @@ (draw:defmethod :default #nil) (update:defmethod :default #nil) (children:defmethod :default (fn [val] (iter.ivalues val))) -(cleanup:defmethod :default #nil) (scene:defmethod :default #nil) (fn descend [t k] (children (. t k) k t)) @@ -51,7 +49,7 @@ (each [k v (descend t key)] (coroutine.yield k v))))) -(children:defmethod :bombs ipairs) +(children:defmethod :bombs iter.reverse-ipairs) (when (= state.level nil) (restart)) @@ -59,15 +57,6 @@ (local screenw (playdate.display.getWidth)) (local screenh (playdate.display.getHeight)) -(update:defmethod :bucket (fn [_ bucket] - (let [crank (playdate.getCrankPosition) - ratio (if (> crank 180) (/ (- 360 crank) -130) (/ crank 130)) - clamped (if (< ratio -1) -1 - (> ratio 1) 1 - ratio) - x (* (/ (+ ratio 1) 2) screenw)] - (set bucket.x x)))) - (fn make-image [w h f] (let [image (gfx.image.new w h)] (gfx.pushContext image) @@ -78,19 +67,38 @@ (fn defsprite [type f] (cache.register-initializer :sprite type f)) (fn sprite [type ?id] (cache.get :sprite type ?id)) +(fn with-image [spr image center-x center-y] + (doto spr (: :setImage image) (: :setCenter center-x center-y))) +(fn with-collision [spr groupmask collidemask ?colliderect] + (doto spr (: :setGroupMask groupmask) (: :setCollidesWithGroupsMask collidemask) + (: :setCollideRect (if ?colliderect ?colliderect (values 0 0 (spr:getSize)))))) + (let [bucketw 50 bucketh 10 radius 4 xoffset (/ bucketw 2) - buckety 220 + buckety 200 image (make-image bucketw bucketh #(gfx.drawRoundRect 0 0 bucketw bucketh radius))] - (defsprite :bucket #(doto $1 (: :setImage image) (: :setCenter 0.5 0))) + (defsprite :bucket #(doto $1 (with-image image 0.5 0) (with-collision 1 2))) (draw:defmethod :bucket (fn [_ {: x}] (doto (sprite :bucket) (: :moveTo x buckety))))) +(update:defmethod :bucket (fn [_ bucket] + (let [crank (playdate.getCrankPosition) + ratio (if (> crank 180) (/ (- 360 crank) -130) (/ crank 130)) + clamped (if (< ratio -1) -1 + (> ratio 1) 1 + ratio) + x (* (/ (+ ratio 1) 2) screenw)] + (set bucket.x x)) + (let [collisions (: (sprite :bucket) :overlappingSprites)] + (each [_ spr (ipairs collisions)] + (print "poof") + (set spr.bomb.defused true))))) + (fn drop-bomb [ctx] (table.insert ctx.bombs {:x ctx.bomber.x :y 30})) (let [image (make-image 20 30 #(gfx.fillRoundRect 0 0 20 30 6))] - (defsprite :bomber #(doto $1 (: :setImage image) (: :setCenter 0.5 0))) + (defsprite :bomber #(with-image $1 image 0.5 0)) (draw:defmethod :bomber (fn [_ {: x}] (doto (sprite :bomber) (: :moveTo x 5))))) @@ -102,25 +110,20 @@ (gfx.sprite.setBackgroundDrawingCallback #(gfx.drawLine 0 33 screenw 33)) (let [image (make-image 14 14 #(gfx.fillCircleAtPoint 7 7 7))] - (defsprite :bombs #(doto $1 (: :setImage image) (: :setCenter 0.5 0.5))) + (defsprite :bombs #(doto $1 (with-image image 0.5 0.5) (with-collision 2 1) (tset :bomb $3))) (draw:defmethod :bombs (fn [_ {: x : y &as bomb}] (doto (sprite :bombs bomb) (: :moveTo x y))))) -(fn bombspeed [ctx] ctx.level) +(fn bombspeed [ctx] (+ ctx.level 5)) (update:defmethod :bombs (fn [_ bomb ibomb ctx] (when (= ctx.state :bombing) (set bomb.y (+ bomb.y (bombspeed ctx))) - (when (> bomb.y screenh) - (set ctx.state :lost))))) - -(cleanup:defmethod :bombs (fn [_ ctx] - (destroy-items :bombs ctx (tbl.keys-matching ctx.bombs #(> $1.y screenh)) #$2))) + (when (or (> bomb.y screenh) bomb.defused) + (destroy-item :bombs bomb ctx ibomb))))) (fn scene-update [keys ctx] (do-to-children keys update ctx) - (each [_ key (ipairs keys)] - (cleanup key ctx)) (do-to-children keys draw ctx)) (scene:defmethod :ingame #(scene-update [:bomber :bombs :bucket] $2))