diff --git a/src/explosion.fnl b/src/explosion.fnl index 8996f14..ac6f53b 100644 --- a/src/explosion.fnl +++ b/src/explosion.fnl @@ -1,10 +1,10 @@ (local reload (require :meta.reload)) (local {: defmulti} (require :meta.multimethod)) -(local tbl (require :meta.table)) +(local {: inc : dec &as tbl} (require :meta.table)) (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 {: make-image : defsprite : sprite : dirty : with-bg-draw : with-image : with-collision} (require :sprite)) (local gfx playdate.graphics) @@ -40,6 +40,7 @@ :bombs [] :bucket {:count 3} :level 1 + :score 0 :state :waiting :scene :ingame})) @@ -53,13 +54,12 @@ (let [bucketw 50 bucketh 10 radius 4 xoffset (/ bucketw 2) - buckety 200 image (make-image bucketw bucketh #(gfx.drawRoundRect 0 0 bucketw bucketh radius))] - (defsprite :bucket #(doto $1 (with-image image 0.5 0) (with-collision 1 2)))) + (defsprite :bucket #(doto $1 (with-image image 0.5 0.5) (with-collision 1 2)))) (fn lose-life [ctx] (let [count ctx.bucket.count] - (set ctx.bucket.count (- count 1)) + (dec ctx.bucket :count) (set ctx.bomber.bombs-left 0) (cache.destroy :bucket count) (destroy-all :bombs ctx) @@ -71,7 +71,7 @@ ratio (if (> crank 180) (/ (- 360 crank) -130) (/ crank 130)) x (* (/ (+ ratio 1) 2) screenw)] (for [ibucket 1 bucket.count] - (let [buckety (- 220 (* (- ibucket 1) 25))] + (let [buckety (- 230 (* (- ibucket 1) 20))] (doto (sprite :bucket ibucket) (: :moveTo x buckety))))))) (let [image (make-image 20 30 #(gfx.fillRoundRect 0 0 20 30 6))] @@ -86,27 +86,30 @@ (fn bombcount [ctx] 50) (fn bombdropframecount [ctx] - (math.ceil (/ 18 (bombspeed ctx)))) - + (math.ceil (/ 25 (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)) + (dec ctx.bomber :bombs-left) (set ctx.bomber.bombframes (bombdropframecount ctx)) true)) +(fn score [ctx] + (set ctx.score (+ ctx.score 1)) + (dirty :background)) + (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) + (inc bomber :x (bombervelocity ctx (- bomber.target-x bomber.x))) + (when (<= (dec bomber :bombframes) 0) (drop-bomb ctx))) (when (and (= ctx.state :bombing) (= bomber.bombs-left 0) (= (length ctx.bombs) 0)) - (set ctx.level (+ ctx.level 1)) + (inc ctx :level) + (dirty :background) (set ctx.state :waiting)) (doto (sprite :bomber) (: :moveTo bomber.x 5)) @@ -116,9 +119,15 @@ (drop-bomb ctx)) (when (playdate.buttonJustPressed :b) (set ctx.level 1) + (set ctx.score 0) + (dirty :background) (set ctx.bucket.count 3)))) -(gfx.sprite.setBackgroundDrawingCallback #(gfx.drawLine 0 33 screenw 33)) +(defsprite :background #(with-bg-draw $1 (fn [] + (gfx.drawLine 0 33 screenw 33) + (gfx.drawText (tostring state.level) 75 8) + (gfx.drawText (tostring state.score) 320 8)))) +(dirty :background) (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)))) @@ -126,7 +135,7 @@ (update:defmethod :bombs (fn [_ bomb ibomb ctx] (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) + (if (> count 0) (do (score ctx) (destroy-item :bombs bomb ctx ibomb)) (> y screenh) (lose-life ctx) (set bomb.y y))))) @@ -141,4 +150,5 @@ (gfx.sprite.update) (playdate.timer.updateTimers) (when (reload.check) - (cache.purge))) + (cache.purge) + (dirty :background))) diff --git a/src/meta/table.fnl b/src/meta/table.fnl index 16392ca..2525ea3 100644 --- a/src/meta/table.fnl +++ b/src/meta/table.fnl @@ -68,4 +68,14 @@ (fn tbl.keys-matching [t f] (icollect [k v (pairs t)] (when (f v k) k))) +(fn tbl.inc [t k ?by] + (let [result (+ (. t k) (or ?by 1))] + (tset t k result) + result)) + +(fn tbl.dec [t k ?by] + (let [result (- (. t k) (or ?by 1))] + (tset t k result) + result)) + tbl \ No newline at end of file diff --git a/src/sprite.fnl b/src/sprite.fnl index 0e4e2d9..5afd4ab 100644 --- a/src/sprite.fnl +++ b/src/sprite.fnl @@ -1,7 +1,7 @@ (local cache (require :cache)) (import :CoreLibs/sprites) -(cache.register-asset :sprite #(doto (playdate.graphics.sprite.new) (: :add)) #($1:remove)) +(cache.register-asset :sprite #(doto (playdate.graphics.sprite.new) (: :add) (: :setUpdatesEnabled false)) #($1:remove)) (local gfx playdate.graphics) @@ -14,11 +14,20 @@ (fn defsprite [type f] (cache.register-initializer :sprite type f)) (fn sprite [type ?id] (cache.get :sprite type ?id)) +(fn dirty [type ?id] (doto (sprite type ?id) (: :markDirty))) +(fn with-draw [spr callback] (set spr.draw callback) spr) +(fn with-bg-draw [spr callback] + (doto spr (with-draw callback) + (: :setSize (playdate.display.getSize)) + (: :setCenter 0 0) + (: :moveTo 0 0) + (: :setZIndex -32768) + (: :setIgnoresDrawOffset true))) (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} +{: make-image : defsprite : sprite : dirty : with-image : with-collision : with-draw : with-bg-draw}