get vision poly almost working

This commit is contained in:
Travis Shears 2026-05-08 11:46:14 +02:00
parent 33482c6291
commit 1045fdc386
Signed by: travisshears
GPG key ID: CB9BF1910F3F7469
2 changed files with 116 additions and 14 deletions

View file

@ -10,6 +10,9 @@
(lambda bump-filter [item other] (lambda bump-filter [item other]
(if (= other.behavior "block") :slide :cross)) (if (= other.behavior "block") :slide :cross))
(lambda vision-bump-filter [other]
(= other.behavior "block"))
(lambda angle-to-direction [angle] (lambda angle-to-direction [angle]
"Convert angle (radians) to compass direction keyword" "Convert angle (radians) to compass direction keyword"
(local tau (* 2 math.pi)) (local tau (* 2 math.pi))
@ -28,6 +31,7 @@
(local height 15) (local height 15)
(local player { (local player {
:x 50 :y 50 :w 25 :h 25 :speed 80 :battery 100 :rot 0 :x 50 :y 50 :w 25 :h 25 :speed 80 :battery 100 :rot 0
:vision-pts []
:hitbox [50 50 width height] :hitbox [50 50 width height]
:init-move false ; nudge the player at start of game to trigger starting collisions :init-move false ; nudge the player at start of game to trigger starting collisions
}) })
@ -38,6 +42,52 @@
(when col.other.on-hit (col.other:on-hit)) (when col.other.on-hit (col.other:on-hit))
(beholder.trigger "PLAYER.HIT" col.other))) (beholder.trigger "PLAYER.HIT" col.other)))
(lambda origin-pt [x y]
(values (+ x (/ width 2)) (+ y (/ height 2))))
(lambda player.cal-vision-points [self]
(let [pts []
(ox oy) (origin-pt self.x self.y)
add-pt (lambda [x y]
(let [(rx ry) (utils.rotate-pt x y ox oy self.rot)]
(table.insert pts [rx ry])))
]
(for [i 1 5]
(add-pt (- ox (* i 5) 50) (- oy (- 50 (* i 5) ))))
(for [i 1 10]
(add-pt (- ox (* i 5)) (- oy 50)))
(add-pt ox (- oy 50)) ; middle pt
(for [i 1 10]
(add-pt (+ ox (* i 5)) (- oy 50)))
(for [i 1 5]
(add-pt (+ ox (* i 5) 50) (- oy (- 50 (* i 5) ))))
pts
)
)
(lambda player.cal-vision-poly [self]
(let [pts (self:cal-vision-points)
(ox oy) (origin-pt self.x self.y)
poly-pts [ox oy]
]
(each [_ pt (ipairs pts)]
(let [
items (bump-world:querySegmentWithCoords ox oy (. pt 1) (. pt 2) vision-bump-filter)
first-item (. items 1)]
(if first-item
(do
(table.insert poly-pts (. first-item :x1))
(table.insert poly-pts (. first-item :y1)))
(do
(table.insert poly-pts (. pt 1))
(table.insert poly-pts (. pt 2))))))
(set self.vision-pts poly-pts)
; (utils.debug-print {: poly-pts})
))
(fn player.update [self dt] (fn player.update [self dt]
(when (= self.init-move false) (when (= self.init-move false)
(set self.init-move true) (set self.init-move true)
@ -62,7 +112,8 @@
(x y cols len) (bump-world:move self new-x new-y bump-filter)] (x y cols len) (bump-world:move self new-x new-y bump-filter)]
(handle-collisions cols) (handle-collisions cols)
(set self.x x) (set self.x x)
(set self.y y)) (set self.y y)
(self:cal-vision-poly))
(if (> self.battery 0) (if (> self.battery 0)
(set self.battery (- self.battery (* dt 2)))))) (set self.battery (- self.battery (* dt 2))))))
(beholder.trigger "PLAYER.POS" self.x self.y) (beholder.trigger "PLAYER.POS" self.x self.y)
@ -99,25 +150,33 @@
(- self.x 3) (- self.y 7))) (- self.x 3) (- self.y 7)))
(lambda draw-vision-debug [self] (lambda player.draw-vision-debug [self]
"draw debug lines and points for player vision" "draw debug lines and points for player vision"
(color.set-color :black) (color.set-color :black)
(love.graphics.push) ; (love.graphics.setPointSize 2)
(let [ox (+ self.x (/ width 2)) ; (utils.debug-print {:pts self.vision-pts :player {:x self.x :y self.y}})
oy (+ self.y (/ height 2)) ; (each [_ pt (pairs self.vision-pts)]
steps 20 ; (love.graphics.points (unpack pt)))
vision-step (/ (/ math.pi 2) steps)] ; 90 deg / 20 (when (> (length self.vision-pts) 2) (love.graphics.polygon "line" self.vision-pts))
(love.graphics.translate ox oy) ; (love.graphics.push)
(love.graphics.rotate (- self.rot (/ (* steps vision-step) 2))) ; (let [ox (+ self.x (/ width 2))
(for [i 1 steps] ; oy (+ self.y (/ height 2))
(love.graphics.rotate vision-step) ; steps 20
(love.graphics.line 0 0 50 0)) ; vision-step (/ (/ math.pi 2) steps)] ; 90 deg / 20
(love.graphics.pop))) ; (love.graphics.translate ox oy)
; (love.graphics.rotate (- self.rot (/ (* steps vision-step) 2)))
; (for [i 1 steps]
; (love.graphics.rotate vision-step)
; (love.graphics.line 0 0 50 0))
; (love.graphics.pop)))
)
; local items, len = world:querySegment(x1,y1,x2,y2,filter)
(fn player.draw-debug [self] (fn player.draw-debug [self]
"draw player hitbox and direction line" "draw player hitbox and direction line"
(color.set-color :black) (color.set-color :black)
(draw-vision-debug self) (self:draw-vision-debug)
(love.graphics.rectangle "line" self.x self.y width height) (love.graphics.rectangle "line" self.x self.y width height)
; (love.graphics.rectangle "line" self.x self.y 1 1) ; (love.graphics.rectangle "line" self.x self.y 1 1)
(love.graphics.push) (love.graphics.push)

View file

@ -1,6 +1,49 @@
; Radian constants at 30-degree increments
(local deg-0 0)
(local deg-30 (/ math.pi 6))
(local deg-60 (/ math.pi 3))
(local deg-90 (/ math.pi 2))
(local deg-120 (* 2 (/ math.pi 3)))
(local deg-150 (* 5 (/ math.pi 6)))
(local deg-180 math.pi)
(local deg-210 (* 7 (/ math.pi 6)))
(local deg-240 (* 4 (/ math.pi 3)))
(local deg-270 (* 3 (/ math.pi 2)))
(local deg-300 (* 5 (/ math.pi 3)))
(local deg-330 (* 11 (/ math.pi 6)))
(local deg-360 (* 2 math.pi))
(lambda debug-print [obj] (lambda debug-print [obj]
(print (fennel.view obj))) (print (fennel.view obj)))
(lambda rotate-pt [x y ox oy theta]
(let [
fix-theta (+ theta deg-90)
cos-theta (math.cos fix-theta)
sin-theta (math.sin fix-theta)
translated-x (- x ox)
translated-y (- y oy)
rotated-x (- (* translated-x cos-theta) (* translated-y sin-theta))
rotated-y (+ (* translated-x sin-theta) (* translated-y cos-theta))]
(values (+ ox rotated-x) (+ oy rotated-y))))
{ {
: debug-print : debug-print
: rotate-pt
: deg-0
: deg-30
: deg-60
: deg-90
: deg-120
: deg-150
: deg-180
: deg-210
: deg-240
: deg-270
: deg-300
: deg-330
: deg-360
} }