add charging_station with charging_pads

This commit is contained in:
Travis Shears 2026-04-15 09:58:24 +02:00
parent 20d7c75b07
commit 753e6ace68
Signed by: travisshears
GPG key ID: CB9BF1910F3F7469
8 changed files with 143 additions and 75 deletions

View file

@ -18,6 +18,7 @@
:black-half-tone [0 0 0 0.25]
})
(fn reset-color []
"reset color to white (no tinting)"
(love.graphics.setColor 1 1 1))
@ -30,9 +31,17 @@
(var player-art nil) ; 25x50 pixels each player is 25x25
(var dust-sprite nil) ; 35x35 pixels
(var battery-bar-sprite nil)
(var walls-sprite nil)
(var walls-batch nil)
(var wall-quads nil)
(local walls {
:sprite nil
:quads []
:batch nil
})
(local objects {
:sprite nil
:quads {}
:list []
})
(local screen
(let [scale 2 canvas-w 800 canvas-h 450]
{ :screen-w (* canvas-w scale)
@ -43,51 +52,84 @@
:canvas nil}))
(local camera {:x 0 :y 0})
(local debug false)
(lambda debug-print [obj]
(print (fennel.view obj)))
(local collider-debug-boxes [])
(local bump-world (bump.newWorld 25))
(local player { :x 50 :y 50 :w 25 :h 25 :speed 80 :battery 100 :rot 0 })
; 16:9 (Modern Widescreen - Recommended)**
; - **640x360** ← Best middle ground
; - 800x450
; - 1024x576
; - 1280x720
; **4:3 (Classic/Arcade Feel)**
; - **320x240** (very retro, but small)
; - **800x600** (spacious, classic 4:3)
; - 1024x768
(fn load-walls []
(set walls.sprite (love.graphics.newImage "assets/walls.png"))
(set walls.batch (love.graphics.newSpriteBatch walls.sprite 2500))
;; load quads
(let [(w h) (walls.sprite:getDimensions)]
(for [i 0 19 1]
(table.insert walls.quads (love.graphics.newQuad (* i 25) 0 25 25 w h))))
;; fill batch
(each [_ row (pairs (. levels :level01 :tiles))]
(each [_ tile (pairs row)]
(let [
x tile.x
y tile.y
id tile.tile-id
colliders (or (. levels.level01.wall-colliders (- id 1)) [])]
(if (and (> id 0) (< id 21)) ;; 1-20 are wall tiles
(do
; (print (fennel.view {:quad (. walls.quads id) : x : y : id}))
(walls.batch:add (. walls.quads id) x y)
(each [_ collider (pairs colliders)]
(bump-world:add {: x : y :name :wall :behavior :block} (+ x collider.x) (+ y collider.y) collider.width collider.height)
(table.insert
collider-debug-boxes
{:x (+ x collider.x) :y (+ y collider.y) :width collider.width :height collider.height}))
))))))
(lambda create-charging-station [x y]
(let [
station {: x : y :type :charging-station}
]
(bump-world:add {: x : y :name :charging-station :behavior :block} x y 25 25)
(table.insert collider-debug-boxes {: x : y :width 25 :height 25})
(fn station.draw [self]
(reset-color)
(love.graphics.draw objects.sprite objects.quads.charging-station self.x self.y)
(love.graphics.draw objects.sprite objects.quads.charging-pad (- self.x 25) self.y)
(love.graphics.draw objects.sprite objects.quads.charging-pad (+ self.x 25) self.y)
(love.graphics.draw objects.sprite objects.quads.charging-pad self.x (+ self.y 25))
)
(bump-world:add {: x : y :name :charging-pad :behavior :hover} (- x 25) y 25 25)
(table.insert collider-debug-boxes {:x (- x 25) : y :width 25 :height 25})
(bump-world:add {: x : y :name :charging-pad :behavior :hover} (+ x 25) y 25 25)
(bump-world:add {: x : y :name :charging-pad :behavior :hover} x (+ y 25) 25 25)
(table.insert objects.list station)))
(fn load-objects []
(set objects.sprite (love.graphics.newImage "assets/objects.png"))
(let [(w h) (objects.sprite:getDimensions)]
(set objects.quads.charging-pad (love.graphics.newQuad 0 0 25 25 w h))
(set objects.quads.charging-station (love.graphics.newQuad 25 0 25 25 w h)))
(each [_ row (pairs (. levels :level01 :tiles))]
(each [_ tile (pairs row)]
(let [
x tile.x
y tile.y
id tile.tile-id]
(when (> id 20) ;; 21+ are object tiles
(when (= id 22) (create-charging-station x y)))))))
(fn love.load []
(love.window.setMode screen.screen-w screen.screen-h)
(tset screen :canvas (love.graphics.newCanvas screen.canvas-w screen.canvas-h))
(bump-world:add player player.x player.y player.w player.h)
;; load world images
(set walls-sprite (love.graphics.newImage "assets/walls.png"))
(set walls-batch (love.graphics.newSpriteBatch walls-sprite 2500))
(set battery-bar-sprite (love.graphics.newImage "assets/battery_bar.png"))
(load-walls)
(load-objects)
;; load wall quads
(set wall-quads [])
(let [(w h) (: walls-sprite :getDimensions)]
(for [i 0 19 1]
(table.insert wall-quads (love.graphics.newQuad (* i 25) 0 25 25 w h))))
;; load tiles
(each [_ row (pairs (. levels :level01 :tiles))]
(each [_ tile (pairs row)]
(let [
x (. tile :x)
y (. tile :y)
id (. tile :tile-id)
colliders (or (. levels.level01.wall-colliders (- id 1)) [])]
(walls-batch:add (. wall-quads id) x y)
; (print (fennel.view colliders))
(each [_ collider (pairs colliders)]
(bump-world:add {: x : y :type "wall"} (+ x collider.x) (+ y collider.y) collider.width collider.height)
(table.insert
collider-debug-boxes
{:x (+ x collider.x) :y (+ y collider.y) :width collider.width :height collider.height})
))))
;; load world images
(set battery-bar-sprite (love.graphics.newImage "assets/battery_bar.png"))
(set player-art
(let [
@ -125,21 +167,13 @@ while 1 do love.event.push('stdin', io.read('*line')) end") :start))
(fn draw-world []
(reset-color)
(love.graphics.draw walls-batch)
(love.graphics.draw walls.batch)
;; draw collider debug boxes
(when debug
(set-color :black)
(each [_ collider (pairs collider-debug-boxes)]
(love.graphics.rectangle "line" collider.x collider.y collider.width collider.height))))
(local has-true? (fn [lst]
(accumulate [found? false _ v (ipairs lst)]
(or found? v))))
; All true
(local all-true? (fn [lst]
(accumulate [result true _ v (ipairs lst)]
(and result v))))
(fn love.update [dt]
; move / rotate player
@ -160,11 +194,13 @@ while 1 do love.event.push('stdin', io.read('*line')) end") :start))
dir-fn (if (or d-key a-key) #(+ $1 $2) #(- $1 $2))
new-x (dir-fn player.x (* player.speed dt (math.cos player.rot)))
new-y (dir-fn player.y (* player.speed dt (math.sin player.rot)))
(x y) (bump-world:move player new-x new-y)]
(tset player :x x)
(tset player :y y))
(if (> player.battery 0)
(tset player :battery (- player.battery (* dt 2))))))
col-filter-fn (lambda [item other]
(if (= other.behavior "block") :slide :cross))
(x y cols len) (bump-world:move player new-x new-y col-filter-fn)]
(tset player :x x)
(tset player :y y))
(if (> player.battery 0)
(tset player :battery (- player.battery (* dt 2))))))
;; Update camera to follow player (keep player centered on screen)
(tset camera :x (- player.x (/ screen.canvas-w 2)))
(tset camera :y (- player.y (/ screen.canvas-h 2))))
@ -229,6 +265,10 @@ while 1 do love.event.push('stdin', io.read('*line')) end") :start))
(love.graphics.pop)
))
(fn draw-objects []
(each [_ obj (pairs objects.list)]
; (print (fennel.view obj))
(obj:draw)))
(fn love.draw []
(love.graphics.setCanvas screen.canvas)
@ -238,6 +278,7 @@ while 1 do love.event.push('stdin', io.read('*line')) end") :start))
(love.graphics.push) ; stores the default coordinate system
(love.graphics.translate (* -1 camera.x) (* -1 camera.y))
(draw-world)
(draw-objects)
(draw-player)
(love.graphics.pop)
(draw-ui)