2025-11-09 06:30:17 -06:00
|
|
|
(local pxl8 (require :pxl8))
|
|
|
|
|
|
2025-11-21 16:44:42 -06:00
|
|
|
(var world nil)
|
|
|
|
|
|
|
|
|
|
(var auto-run? false)
|
2025-11-28 14:41:35 -06:00
|
|
|
(var auto-run-cancel-key nil)
|
2025-11-19 22:18:08 -06:00
|
|
|
(var cam-pitch 0)
|
2025-11-09 06:30:17 -06:00
|
|
|
(var cam-x 1000)
|
2025-11-15 08:30:51 -06:00
|
|
|
(var cam-y 64)
|
2025-11-15 14:23:53 -06:00
|
|
|
(var cam-yaw 0)
|
2025-11-19 22:18:08 -06:00
|
|
|
(var cam-z 1000)
|
2025-11-21 16:44:42 -06:00
|
|
|
(var cursor-look? true)
|
|
|
|
|
|
|
|
|
|
(var smooth-cam-x 1000)
|
|
|
|
|
(var smooth-cam-z 1000)
|
|
|
|
|
(local cam-smoothing 0.25)
|
|
|
|
|
|
|
|
|
|
(local bob-amount 4.0)
|
|
|
|
|
(local bob-speed 8.0)
|
|
|
|
|
(var bob-time 0)
|
2025-11-11 21:24:53 -06:00
|
|
|
(local cell-size 64)
|
2025-11-21 16:44:42 -06:00
|
|
|
(local cursor-sensitivity 0.008)
|
2025-11-15 08:30:51 -06:00
|
|
|
(local gravity -800)
|
2025-11-20 20:55:45 -06:00
|
|
|
(local grid-size 64)
|
2025-11-15 14:23:53 -06:00
|
|
|
(var grounded? true)
|
2025-11-15 08:30:51 -06:00
|
|
|
(local ground-y 64)
|
2025-11-15 14:23:53 -06:00
|
|
|
(local jump-force 175)
|
2025-11-15 08:30:51 -06:00
|
|
|
(local land-recovery-speed 20)
|
2025-11-19 22:18:08 -06:00
|
|
|
(local land-squash-amount -4)
|
|
|
|
|
(var land-squash 0)
|
2025-11-15 14:23:53 -06:00
|
|
|
(local max-pitch 1.5)
|
|
|
|
|
(local move-speed 200)
|
|
|
|
|
(local turn-speed 2.0)
|
|
|
|
|
(var velocity-y 0)
|
2025-11-09 06:30:17 -06:00
|
|
|
|
|
|
|
|
(fn init []
|
|
|
|
|
(set world (pxl8.world_new))
|
|
|
|
|
(let [result (pxl8.world_generate world {
|
2025-11-20 20:55:45 -06:00
|
|
|
:type pxl8.PROCGEN_ROOMS
|
|
|
|
|
:width 64
|
|
|
|
|
:height 64
|
2025-11-09 06:30:17 -06:00
|
|
|
:seed 42
|
2025-11-20 20:55:45 -06:00
|
|
|
:min_room_size 5
|
|
|
|
|
:max_room_size 10
|
|
|
|
|
:num_rooms 20})]
|
2025-11-09 06:30:17 -06:00
|
|
|
(if (< result 0)
|
2025-11-20 20:55:45 -06:00
|
|
|
(pxl8.error (.. "Failed to generate rooms - result: " result))
|
2025-11-11 23:26:51 -06:00
|
|
|
(let [floor-tex (pxl8.procgen_tex {:name "floor"
|
|
|
|
|
:seed 11111
|
|
|
|
|
:width 64
|
|
|
|
|
:height 64
|
|
|
|
|
:base_color 19})
|
|
|
|
|
ceiling-tex (pxl8.procgen_tex {:name "ceiling"
|
|
|
|
|
:seed 22222
|
|
|
|
|
:width 64
|
|
|
|
|
:height 64
|
|
|
|
|
:base_color 1})
|
|
|
|
|
wall-tex (pxl8.procgen_tex {:name "wall"
|
|
|
|
|
:seed 12345
|
|
|
|
|
:width 64
|
|
|
|
|
:height 64
|
|
|
|
|
:base_color 4})]
|
|
|
|
|
|
|
|
|
|
(let [result (pxl8.world_apply_textures world [
|
|
|
|
|
{:name "floor"
|
|
|
|
|
:texture_id floor-tex
|
|
|
|
|
:rule (fn [normal] (> normal.y 0.7))}
|
|
|
|
|
{:name "ceiling"
|
|
|
|
|
:texture_id ceiling-tex
|
|
|
|
|
:rule (fn [normal] (< normal.y -0.7))}
|
|
|
|
|
{:name "wall"
|
|
|
|
|
:texture_id wall-tex
|
|
|
|
|
:rule (fn [normal] (and (<= normal.y 0.7) (>= normal.y -0.7)))}])]
|
|
|
|
|
(when (< result 0)
|
|
|
|
|
(pxl8.error (.. "Failed to apply textures - result: " result))))))))
|
2025-11-09 06:30:17 -06:00
|
|
|
|
|
|
|
|
(fn update [dt]
|
2025-11-20 20:55:45 -06:00
|
|
|
(when (pxl8.key_pressed "`")
|
2025-11-28 14:41:35 -06:00
|
|
|
(set auto-run? (not auto-run?))
|
|
|
|
|
(when (and auto-run? (pxl8.key_down "w"))
|
|
|
|
|
(set auto-run-cancel-key "w")))
|
|
|
|
|
(when (and auto-run? (not auto-run-cancel-key) (or (pxl8.key_down "w") (pxl8.key_down "s")))
|
|
|
|
|
(set auto-run? false)
|
|
|
|
|
(when (pxl8.key_down "s")
|
|
|
|
|
(set auto-run-cancel-key "s")))
|
|
|
|
|
(when (and auto-run-cancel-key (not (pxl8.key_down auto-run-cancel-key)))
|
|
|
|
|
(set auto-run-cancel-key nil))
|
2025-11-20 20:55:45 -06:00
|
|
|
|
2025-11-09 06:30:17 -06:00
|
|
|
(when (pxl8.world_is_loaded world)
|
|
|
|
|
(let [forward-x (- (math.sin cam-yaw))
|
|
|
|
|
forward-z (- (math.cos cam-yaw))
|
|
|
|
|
right-x (math.cos cam-yaw)
|
|
|
|
|
right-z (- (math.sin cam-yaw))
|
2025-11-11 21:24:53 -06:00
|
|
|
grid-max (* grid-size cell-size)
|
|
|
|
|
move-delta (* move-speed dt)]
|
2025-11-09 06:30:17 -06:00
|
|
|
|
|
|
|
|
(var moving false)
|
2025-11-11 21:35:34 -06:00
|
|
|
(var move-forward 0)
|
|
|
|
|
(var move-right 0)
|
2025-11-09 06:30:17 -06:00
|
|
|
|
2025-11-20 20:55:45 -06:00
|
|
|
(when (or (pxl8.key_down "w") auto-run?)
|
2025-11-15 08:30:51 -06:00
|
|
|
(set move-forward (+ move-forward 1)))
|
2025-11-09 06:30:17 -06:00
|
|
|
|
2025-11-28 14:41:35 -06:00
|
|
|
(when (and (pxl8.key_down "s") (not= auto-run-cancel-key "s"))
|
2025-11-15 08:30:51 -06:00
|
|
|
(set move-forward (- move-forward 1)))
|
2025-11-09 06:30:17 -06:00
|
|
|
|
2025-11-19 22:18:08 -06:00
|
|
|
(when (pxl8.key_down "a")
|
2025-11-15 08:30:51 -06:00
|
|
|
(set move-right (- move-right 1)))
|
2025-11-09 06:30:17 -06:00
|
|
|
|
2025-11-19 22:18:08 -06:00
|
|
|
(when (pxl8.key_down "d")
|
2025-11-15 08:30:51 -06:00
|
|
|
(set move-right (+ move-right 1)))
|
|
|
|
|
|
|
|
|
|
(set moving (or (not= move-forward 0) (not= move-right 0)))
|
2025-11-09 06:30:17 -06:00
|
|
|
|
2025-11-11 21:35:34 -06:00
|
|
|
(var new-x cam-x)
|
|
|
|
|
(var new-z cam-z)
|
|
|
|
|
|
|
|
|
|
(when moving
|
2025-11-15 08:30:51 -06:00
|
|
|
(let [len (math.sqrt (+ (* move-forward move-forward) (* move-right move-right)))
|
|
|
|
|
norm-forward (/ move-forward len)
|
|
|
|
|
norm-right (/ move-right len)]
|
|
|
|
|
(set new-x (+ new-x (* move-delta (+ (* forward-x norm-forward) (* right-x norm-right)))))
|
|
|
|
|
(set new-z (+ new-z (* move-delta (+ (* forward-z norm-forward) (* right-z norm-right)))))))
|
2025-11-11 21:35:34 -06:00
|
|
|
|
2025-11-11 21:24:53 -06:00
|
|
|
(when (and (>= new-x 0) (<= new-x grid-max)
|
|
|
|
|
(>= new-z 0) (<= new-z grid-max))
|
2025-11-21 16:44:42 -06:00
|
|
|
(let [(resolved-x resolved-y resolved-z) (pxl8.world_resolve_collision world cam-x cam-y cam-z new-x cam-y new-z 5)]
|
|
|
|
|
(set cam-x resolved-x)
|
|
|
|
|
(set cam-z resolved-z)))
|
|
|
|
|
|
|
|
|
|
(set smooth-cam-x (+ (* smooth-cam-x (- 1 cam-smoothing)) (* cam-x cam-smoothing)))
|
|
|
|
|
(set smooth-cam-z (+ (* smooth-cam-z (- 1 cam-smoothing)) (* cam-z cam-smoothing)))
|
2025-11-09 06:30:17 -06:00
|
|
|
|
2025-11-21 16:44:42 -06:00
|
|
|
(when cursor-look?
|
2025-11-19 22:18:08 -06:00
|
|
|
(let [dx (pxl8.mouse_dx)
|
|
|
|
|
dy (pxl8.mouse_dy)]
|
2025-11-21 16:44:42 -06:00
|
|
|
(set cam-yaw (- cam-yaw (* dx cursor-sensitivity)))
|
2025-11-19 22:18:08 -06:00
|
|
|
(set cam-pitch (math.max (- max-pitch)
|
|
|
|
|
(math.min max-pitch
|
2025-11-21 16:44:42 -06:00
|
|
|
(- cam-pitch (* dy cursor-sensitivity)))))))
|
2025-11-19 22:18:08 -06:00
|
|
|
|
2025-11-21 16:44:42 -06:00
|
|
|
(when (and (not cursor-look?) (pxl8.key_down "left"))
|
2025-11-09 06:30:17 -06:00
|
|
|
(set cam-yaw (+ cam-yaw (* turn-speed dt))))
|
|
|
|
|
|
2025-11-21 16:44:42 -06:00
|
|
|
(when (and (not cursor-look?) (pxl8.key_down "right"))
|
2025-11-09 06:30:17 -06:00
|
|
|
(set cam-yaw (- cam-yaw (* turn-speed dt))))
|
|
|
|
|
|
2025-11-21 16:44:42 -06:00
|
|
|
(when (and (not cursor-look?) (pxl8.key_down "up"))
|
2025-11-11 21:24:53 -06:00
|
|
|
(set cam-pitch (math.min max-pitch (+ cam-pitch (* turn-speed dt)))))
|
2025-11-09 06:30:17 -06:00
|
|
|
|
2025-11-21 16:44:42 -06:00
|
|
|
(when (and (not cursor-look?) (pxl8.key_down "down"))
|
2025-11-11 21:24:53 -06:00
|
|
|
(set cam-pitch (math.max (- max-pitch) (- cam-pitch (* turn-speed dt)))))
|
2025-11-09 06:30:17 -06:00
|
|
|
|
2025-11-15 08:30:51 -06:00
|
|
|
(when (and (pxl8.key_pressed "space") grounded?)
|
|
|
|
|
(set velocity-y jump-force)
|
|
|
|
|
(set grounded? false))
|
|
|
|
|
|
|
|
|
|
(set velocity-y (+ velocity-y (* gravity dt)))
|
|
|
|
|
(set cam-y (+ cam-y (* velocity-y dt)))
|
|
|
|
|
|
|
|
|
|
(when (<= cam-y ground-y)
|
|
|
|
|
(when (not grounded?)
|
|
|
|
|
(set land-squash land-squash-amount))
|
|
|
|
|
(set cam-y ground-y)
|
|
|
|
|
(set velocity-y 0)
|
|
|
|
|
(set grounded? true))
|
|
|
|
|
|
|
|
|
|
(when (< land-squash 0)
|
|
|
|
|
(set land-squash (math.min 0 (+ land-squash (* land-recovery-speed dt)))))
|
|
|
|
|
|
|
|
|
|
(if (and moving grounded?)
|
2025-11-09 06:30:17 -06:00
|
|
|
(set bob-time (+ bob-time (* dt bob-speed)))
|
|
|
|
|
(let [target-phase (* (math.floor (/ bob-time math.pi)) math.pi)]
|
|
|
|
|
(set bob-time (+ (* bob-time 0.8) (* target-phase 0.2))))))))
|
|
|
|
|
|
|
|
|
|
(fn frame []
|
2025-11-15 11:55:00 -06:00
|
|
|
(pxl8.clear 0)
|
2025-11-09 06:30:17 -06:00
|
|
|
|
|
|
|
|
(when (pxl8.world_is_loaded world)
|
|
|
|
|
(let [bob-offset (* (math.sin bob-time) bob-amount)
|
2025-11-15 08:30:51 -06:00
|
|
|
eye-y (+ cam-y bob-offset land-squash)
|
2025-11-09 06:30:17 -06:00
|
|
|
forward-x (- (math.sin cam-yaw))
|
|
|
|
|
forward-z (- (math.cos cam-yaw))
|
2025-11-21 16:44:42 -06:00
|
|
|
target-x (+ smooth-cam-x forward-x)
|
2025-11-09 06:30:17 -06:00
|
|
|
target-y (+ eye-y (math.sin cam-pitch))
|
2025-11-21 16:44:42 -06:00
|
|
|
target-z (+ smooth-cam-z forward-z)]
|
2025-11-09 06:30:17 -06:00
|
|
|
|
|
|
|
|
(pxl8.clear_zbuffer)
|
|
|
|
|
(pxl8.set_backface_culling true)
|
|
|
|
|
(pxl8.set_wireframe false)
|
|
|
|
|
|
|
|
|
|
(let [aspect (/ (pxl8.get_width) (pxl8.get_height))
|
|
|
|
|
fov 1.047]
|
|
|
|
|
(pxl8.set_projection (pxl8.mat4_perspective fov aspect 1.0 4096.0)))
|
|
|
|
|
|
|
|
|
|
(pxl8.set_view (pxl8.mat4_lookat
|
2025-11-21 16:44:42 -06:00
|
|
|
[smooth-cam-x eye-y smooth-cam-z]
|
2025-11-09 06:30:17 -06:00
|
|
|
[target-x target-y target-z]
|
|
|
|
|
[0 1 0]))
|
|
|
|
|
|
|
|
|
|
(pxl8.set_model (pxl8.mat4_identity))
|
|
|
|
|
|
2025-11-21 16:44:42 -06:00
|
|
|
(pxl8.world_render world [smooth-cam-x eye-y smooth-cam-z])
|
2025-11-10 10:24:27 -06:00
|
|
|
|
2025-11-20 10:24:33 -06:00
|
|
|
(let [cx (/ (pxl8.get_width) 2)
|
|
|
|
|
cy (/ (pxl8.get_height) 2)
|
|
|
|
|
crosshair-size 4
|
|
|
|
|
red-color 18]
|
|
|
|
|
(pxl8.line (- cx crosshair-size) cy (+ cx crosshair-size) cy red-color)
|
|
|
|
|
(pxl8.line cx (- cy crosshair-size) cx (+ cy crosshair-size) red-color))
|
|
|
|
|
|
2025-11-19 22:18:08 -06:00
|
|
|
(pxl8.text (.. "fps: " (string.format "%.1f" (pxl8.get_fps))) 5 5 12)
|
|
|
|
|
(pxl8.text (.. "pos: " (string.format "%.0f" cam-x) ","
|
2025-11-10 10:24:27 -06:00
|
|
|
(string.format "%.0f" cam-y) ","
|
2025-11-19 22:18:08 -06:00
|
|
|
(string.format "%.0f" cam-z)) 5 15 12))))
|
2025-11-09 06:30:17 -06:00
|
|
|
|
|
|
|
|
{:init init
|
|
|
|
|
:update update
|
|
|
|
|
:frame frame}
|