diff --git a/game/entities/bomb.fnl b/game/entities/bomb.fnl index 771c588..8961c92 100644 --- a/game/entities/bomb.fnl +++ b/game/entities/bomb.fnl @@ -27,6 +27,8 @@ (fn Bomb.explode [bomb rules] (Bomb.set-state bomb :exploding 0.5) + (set bomb.solid nil) + (set bomb.deadly true) (rules.explode-bomb bomb)) (fn Bomb.update [bomb dt rules] @@ -37,9 +39,9 @@ :exploding (rules.clear-bomb bomb)))) (fn Bomb.new [] - {:state :ticking :timer 3 :draw (util.fn Bomb :draw) :update (util.fn Bomb :update)}) + {:state :ticking :timer 3 :solid true :draw (util.fn Bomb :draw) :update (util.fn Bomb :update)}) (fn Bomb.new-explosion [] - {:state :exploding :timer 0.5 :draw (util.fn Bomb :draw) :update (util.fn Bomb :update)}) + {:state :exploding :timer 0.5 :deadly true :draw (util.fn Bomb :draw) :update (util.fn Bomb :update)}) Bomb diff --git a/game/entities/bomberman.fnl b/game/entities/bomberman.fnl index 97abf08..52b8f58 100644 --- a/game/entities/bomberman.fnl +++ b/game/entities/bomberman.fnl @@ -1,6 +1,7 @@ (local util (require :lib.util)) (local dim (require :game.dim)) (local {: direct : move} (util.require :game.entity)) +(local {: edge : vec*} (util.require :game.helpers)) (local map (require :game.tilemap)) (local bomberman {}) @@ -9,9 +10,22 @@ (fn bomberman.draw [entity] (love.graphics.setColor 0.2 0.2 0.2) (love.graphics.circle :fill (. entity.pos 1) (. entity.pos 2) (/ dim.tilesize 2))) + +(fn collides? [x y rules] + (-?> [x y] + (map.world-to-tile) + (rules.tile-at) + (. :solid))) + (fn bomberman.update [entity dt rules] (set entity.vel (direct bomberman.keymap (* dim.tilesize 3))) - (set entity.pos (move entity.pos entity.vel dt)) + (local [x y] entity.pos) + (local [dx dy] (vec* entity.vel dt)) + (let [xedge (edge x dx (/ dim.tilesize 2)) + xn (if (collides? xedge y rules) x (+ x dx)) + yedge (edge y dy (/ dim.tilesize 2)) + yn (if (collides? x yedge rules) y (+ y dy))] + (set entity.pos [xn yn])) (when (love.keyboard.isDown bomberman.keymap.bomb) (rules.place-bomb (map.world-to-tile entity.pos)))) diff --git a/game/helpers.fnl b/game/helpers.fnl index f2ccb16..3453f85 100644 --- a/game/helpers.fnl +++ b/game/helpers.fnl @@ -32,4 +32,10 @@ (fn all-coordinates [w h] (values coordinate-iterator {: w : h :x 0 :y 0})) -{: dir-from-key : vec* : vec+ : vec-op : all-coordinates} +(fn edge [c dc neg-offset ?pos-offset] + (local pos-offset (if (= ?pos-offset nil) neg-offset ?pos-offset)) + (if (= dc 0) c + (< dc 0) (+ c dc (- neg-offset)) + (+ c dc pos-offset))) + +{: dir-from-key : vec* : vec+ : vec-op : all-coordinates : edge} diff --git a/game/init.fnl b/game/init.fnl index c09be2c..9ebbf7e 100644 --- a/game/init.fnl +++ b/game/init.fnl @@ -10,17 +10,20 @@ (local map (require :game.tilemap)) (local tile (require :game.tiles)) (local bomberman (require :game.entities.bomberman)) +(local rules (require :game.rules)) (modes:register :game gamemode) -(set state.entities [(bomberman.new [10 10])]) +(set state.entities [(bomberman.new [48 48])]) (set state.map (map.new-tilemap 28 31 tile.bombertile (tile.itile-named tile.bombertile :empty))) (set state.bombs (map.new-entitymap state.map.w state.map.h)) +(rules.generate-maze state.map) (command.add nil { "love:game" (fn [] (let [node (core.root_view:get_active_node)] (node:add_view (ModeView gamemode)))) + "love:regenerate-maze" #(rules.generate-maze state.map) }) {} diff --git a/game/rules.fnl b/game/rules.fnl index df8bccb..e890d3e 100644 --- a/game/rules.fnl +++ b/game/rules.fnl @@ -6,8 +6,9 @@ (local Rules {}) -(fn tile-at [[x y]] +(fn Rules.tile-at [[x y]] (map.tile-at-overlay x y [state.bombs state.map])) +(local tile-at Rules.tile-at) (fn Rules.place-bomb [[x y]] (when (. (tile-at [x y]) :empty) @@ -34,5 +35,22 @@ (each [_ [dx dy] (ipairs [[-1 0] [1 0] [0 -1] [0 1]])] (explode-in-dir (+ bomb.x dx) (+ bomb.y dy) dx dy 1))) +(fn Rules.generate-maze [tilemap] + (let [empty (tileset.itile-named tilemap.tileset :empty) + wall (tileset.itile-named tilemap.tileset :strongwall) + weak (tileset.itile-named tilemap.tileset :weakwall)] + (for [x 0 (- tilemap.w 1)] (for [y 0 (- tilemap.h 1)] + (map.set-itile-at x y tilemap + (if (or (= y 0) (= y (- tilemap.h 1)) (= x 0) (= x (- tilemap.w 1))) + wall + + (and (= (% x 2) 0) (= (% y 2) 0)) + wall + + (< (math.random) 0.3) + weak + + empty)))))) + Rules diff --git a/game/tilemap.fnl b/game/tilemap.fnl index 075f929..a14effd 100644 --- a/game/tilemap.fnl +++ b/game/tilemap.fnl @@ -24,7 +24,7 @@ (let [tile (tile-at x y tilemap)] (if (= tile nil) (tile-at-overlay x y tilemaps (+ itilemap 1)) - tile))))) + (values tile tilemap)))))) (fn new-tilemap [w h tileset ?itile] (local tilemap {: w : h : tileset}) @@ -49,11 +49,14 @@ (fn draw-tilemaps [x y tilemaps] (local base-tilemap (. tilemaps (length tilemaps))) (each [tx ty (all-coordinates base-tilemap.w base-tilemap.h)] - (let [tile (tile-at-overlay tx ty tilemaps)] - (when (and tile tile.draw) - (tile.draw (+ x (* tx dim.tilesize) (/ dim.tilesize 2)) - (+ y (* ty dim.tilesize) (/ dim.tilesize 2)) - tile))))) + (let [(tile tilemap) (tile-at-overlay tx ty tilemaps) + xt (+ x (* tx dim.tilesize) (/ dim.tilesize 2)) + yt (+ y (* ty dim.tilesize) (/ dim.tilesize 2))] + (if (and tile tile.draw) + (tile.draw xt yt tile) + + (and tile tilemap.tileset tilemap.tileset.draw) + (tilemap.tileset.draw tile xt yt))))) (fn update-entitymap [tilemap ...] (each [_ entity (ipairs (lume.clone tilemap.entities))] diff --git a/game/tiles.fnl b/game/tiles.fnl index 24ebc8a..a4e5a5b 100644 --- a/game/tiles.fnl +++ b/game/tiles.fnl @@ -29,13 +29,13 @@ [{:name :empty :empty true} {:name :strongwall - :wall true} + :solid true} {:name :weakwall - :wall true + :solid true :breakable true} {:name :dot :edible true} - ] (util.fn tileset :bomber-tile-draw))) + ] (util.fn tileset :bombertile-draw))) tileset