diff --git a/src/cache.fnl b/src/cache.fnl index 18a8c24..e7ad7d1 100644 --- a/src/cache.fnl +++ b/src/cache.fnl @@ -51,7 +51,4 @@ (each [type _ (pairs cache.caches)] (cache.destroy type))) -(import :CoreLibs/sprites) -(cache.register-asset :sprite #(doto (playdate.graphics.sprite.new) (: :add)) #($1:remove)) - cache \ No newline at end of file diff --git a/src/explosion.fnl b/src/explosion.fnl index 190fdf5..1b939a7 100644 --- a/src/explosion.fnl +++ b/src/explosion.fnl @@ -4,10 +4,10 @@ (local iter (require :meta.iter)) (local state (require :state)) (local cache (require :cache)) +(local {: make-image : defsprite : sprite : with-image : with-collision} (require :sprite)) (local gfx playdate.graphics) -(local draw (defmulti #$1)) (local update (defmulti #$1)) (local children (defmulti #$2)) (local scene (defmulti #$1)) @@ -23,7 +23,6 @@ (each [_ index (ipairs (tbl.sorted indexes #(> $1 $2)))] (destroy-item type (get-id ?f-id index ctx type) ctx index))) -(draw:defmethod :default #nil) (update:defmethod :default #nil) (children:defmethod :default (fn [val] (iter.ivalues val))) (scene:defmethod :default #nil) @@ -41,14 +40,8 @@ :bombs [] :bucket {:count 3} :level 1 - :state :waiting :scene :ingame})) -(fn children-keylist [keys _ t] - (iter.coro-iter #(each [_ key (ipairs keys)] - (each [k v (descend t key)] - (coroutine.yield k v))))) - (children:defmethod :bombs iter.reverse-ipairs) (when (= state.level nil) @@ -57,22 +50,6 @@ (local screenw (playdate.display.getWidth)) (local screenh (playdate.display.getHeight)) -(fn make-image [w h f] - (let [image (gfx.image.new w h)] - (gfx.pushContext image) - (f image w h) - (gfx.popContext) - image)) - -(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 200 @@ -82,33 +59,53 @@ (fn lose-life [ctx] (let [count ctx.bucket.count] (set ctx.bucket.count (- count 1)) + (set ctx.bomber.bombs-left 0) (cache.destroy :bucket count) (destroy-all :bombs ctx) - (set ctx.bombs []) - (set ctx.state :waiting))) + (set ctx.bombs []))) (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)] (for [ibucket 1 bucket.count] (let [buckety (- 220 (* (- ibucket 1) 25))] (doto (sprite :bucket ibucket) (: :moveTo x buckety))))))) -(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 #(with-image $1 image 0.5 0)) - (draw:defmethod :bomber (fn [_ {: x}] - (doto (sprite :bomber) (: :moveTo x 5))))) + (defsprite :bomber #(with-image $1 image 0.5 0))) -(update:defmethod :bomber (fn [_ _ _ ctx] +(fn bomberspeed [ctx] (* (+ ctx.level 4) 2)) +(fn bombervelocity [ctx dx] + (let [sign (if (< dx 0) -1 1) + speed (math.min (bomberspeed ctx) (math.abs dx))] + (* speed sign))) +(fn bombspeed [ctx] (+ ctx.level 3)) +(fn bombcount [ctx] 50) + +(fn bombdropframecount [ctx] + (math.ceil (/ 18 (bombspeed ctx)))) + + +(fn drop-bomb [ctx] + (when (> ctx.bomber.bombs-left 0) + (table.insert ctx.bombs {:x ctx.bomber.x :y 30}) + (set ctx.bomber.bombs-left (- ctx.bomber.bombs-left 1)) + (set ctx.bomber.bombframes (bombdropframecount ctx)) + true)) + +(update:defmethod :bomber (fn [_ bomber _ ctx] + (when (> bomber.bombs-left 0) + (when (or (= bomber.target-x nil) (= bomber.x bomber.target-x)) + (set bomber.target-x (math.random 10 (- screenw 10)))) + (set bomber.x (+ bomber.x (bombervelocity ctx (- bomber.target-x bomber.x)))) + (set bomber.bombframes (- bomber.bombframes 1)) + (when (<= bomber.bombframes 0) + (drop-bomb ctx))) + + (doto (sprite :bomber) (: :moveTo bomber.x 5)) (when (playdate.buttonJustPressed :a) - (set ctx.state :bombing) + (set bomber.bombs-left (bombcount ctx)) (drop-bomb ctx)) (when (playdate.buttonJustPressed :b) (set ctx.bucket.count 3)))) @@ -118,19 +115,15 @@ (let [image (make-image 14 14 #(gfx.fillCircleAtPoint 7 7 7))] (defsprite :bombs #(doto $1 (with-image image 0.5 0.5) (with-collision 2 1) (tset :bomb $3)))) -(fn bombspeed [ctx] (+ ctx.level 3)) - (update:defmethod :bombs (fn [_ bomb ibomb ctx] - (when (= ctx.state :bombing) - (let [spr (doto (sprite :bombs bomb) (: :moveTo bomb.x bomb.y)) - (_ y _ count) (spr:moveWithCollisions bomb.x (+ bomb.y (bombspeed ctx)))] - (if (> count 0) (destroy-item :bombs bomb ctx ibomb) - (> y screenh) (lose-life ctx) - (set bomb.y y)))))) + (let [spr (doto (sprite :bombs bomb) (: :moveTo bomb.x bomb.y)) + (_ y _ count) (spr:moveWithCollisions bomb.x (+ bomb.y (bombspeed ctx)))] + (if (> count 0) (destroy-item :bombs bomb ctx ibomb) + (> y screenh) (lose-life ctx) + (set bomb.y y))))) (fn scene-update [keys ctx] - (do-to-children keys update ctx) - (do-to-children keys draw ctx)) + (do-to-children keys update ctx)) (scene:defmethod :ingame #(scene-update [:bomber :bombs :bucket] $2)) diff --git a/src/sprite.fnl b/src/sprite.fnl new file mode 100644 index 0000000..0e4e2d9 --- /dev/null +++ b/src/sprite.fnl @@ -0,0 +1,24 @@ +(local cache (require :cache)) +(import :CoreLibs/sprites) + +(cache.register-asset :sprite #(doto (playdate.graphics.sprite.new) (: :add)) #($1:remove)) + +(local gfx playdate.graphics) + +(fn make-image [w h f] + (let [image (gfx.image.new w h)] + (gfx.pushContext image) + (f image w h) + (gfx.popContext) + image)) + +(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)))))) + +{: make-image : defsprite : sprite : with-image : with-collision}