Rewrite rope #11
120
chameleonic.p8
120
chameleonic.p8
@ -7,6 +7,10 @@ real_modules={}
|
|||||||
|
|
||||||
frame=0
|
frame=0
|
||||||
function _init()
|
function _init()
|
||||||
|
-- cls(0)
|
||||||
|
-- for i in _stepfrom(0.5,-2.5) do print(i) end
|
||||||
|
-- assert(false)
|
||||||
|
|
||||||
_doall("init") end
|
_doall("init") end
|
||||||
function _update()
|
function _update()
|
||||||
frame+=1
|
frame+=1
|
||||||
@ -1096,59 +1100,99 @@ end
|
|||||||
-- TODO: Upon adding a point, start from there to see if we need another
|
-- TODO: Upon adding a point, start from there to see if we need another
|
||||||
-- rather than adding at most one
|
-- rather than adding at most one
|
||||||
function rope:_drag1(n1,ax1_new,ay1_new)
|
function rope:_drag1(n1,ax1_new,ay1_new)
|
||||||
local ax1_old,ay1_old=n1.ax,n1.ay
|
local function _sweep_radar(ax_pivot,ay_pivot,ax_far0,ay_far0,ax_far1,ay_far1)
|
||||||
local n0=n1.prev
|
if ax_far0==ax_far1 then
|
||||||
|
local ax_far=ax_far0
|
||||||
|
local ax0,ax1=_mnmx(ax_pivot,ax_far)
|
||||||
|
|
||||||
if n0!=nil then
|
ay_far_old=ay_far0
|
||||||
local ax0,ay0=n0.ax,n0.ay
|
for ay_far_new in _stepfrom(ay_far0,ay_far1) do
|
||||||
for _,anchor in level:anchor_points() do
|
for _,anchor in level:anchor_points() do
|
||||||
if
|
if
|
||||||
-- NOTE: Do we need to look at the new path too? Something
|
(ax0<=anchor.ax and anchor.ax<=ax1) and
|
||||||
-- just feels wrong about this check.
|
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far,ay_far_old)!=
|
||||||
-- Really our goal is to figure out if moving the end of the
|
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far,ay_far_new)
|
||||||
-- path crosses over the anchor, which feels like a point/triangle
|
|
||||||
-- collision
|
|
||||||
-- We also want to pick the anchor that the ray sweeps over first, not
|
|
||||||
-- the closest one.
|
|
||||||
-- Maybe we should
|
|
||||||
-- (1) sort by angle difference from the original line
|
|
||||||
-- (2) ignore cases where the angle is not between the two lines
|
|
||||||
-- (3) ignore cases where the created point is further from the original point
|
|
||||||
-- than the _intended_ one would be
|
|
||||||
-- Note that if x or y is held constant, this can be implemented
|
|
||||||
-- with a sort on x or y. For our game this is true.
|
|
||||||
--
|
|
||||||
_in_box(anchor.ax,anchor.ay,ax0,ay0,ax1_old,ay1_old) and
|
|
||||||
_which_side(anchor.ax,anchor.ay,ax0,ay0,ax1_old,ay1_old) !=
|
|
||||||
_which_side(anchor.ax,anchor.ay,ax0,ay0,ax1_new,ay1_new)
|
|
||||||
then
|
then
|
||||||
local n05={ax=anchor.ax,ay=anchor.ay,prev=n0,next=n1}
|
return anchor
|
||||||
n0.next = n05
|
|
||||||
n1.prev = n05
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
ay_far_old=ay_far_new
|
||||||
|
end
|
||||||
|
elseif ay_far0==ay_far1 then
|
||||||
|
local ay_far=ay_far0
|
||||||
|
local ay0,ay1=_mnmx(ay_pivot,ay_far)
|
||||||
|
|
||||||
|
ax_far_old=ax_far0
|
||||||
|
for ax_far_new in _stepfrom(ax_far0,ax_far1) do
|
||||||
|
for _,anchor in level:anchor_points() do
|
||||||
|
if
|
||||||
|
(ay0<=anchor.ay and anchor.ay<=ay1) and
|
||||||
|
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far_old,ay_far)!=
|
||||||
|
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far_new,ay_far)
|
||||||
|
then
|
||||||
|
return anchor
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ax_far_old=ax_far_new
|
||||||
|
end
|
||||||
|
else
|
||||||
|
assert(false, "wtf?")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ax1_old,ay1_old=n1.ax,n1.ay
|
||||||
|
|
||||||
|
local n0=n1.prev
|
||||||
|
while true do
|
||||||
|
if (n0==nil) break
|
||||||
|
local anch=_sweep_radar(n0.ax,n0.ay,ax1_old,ay1_old,ax1_new,ay1_new)
|
||||||
|
if (anch==nil) break
|
||||||
|
local n05={ax=anch.ax,ay=anch.ay,prev=n0,next=n1}
|
||||||
|
n0.next=n05
|
||||||
|
n1.prev=n05
|
||||||
|
n0=n05
|
||||||
end
|
end
|
||||||
|
|
||||||
local n2=n1.next
|
local n2=n1.next
|
||||||
if n2!=nil then
|
while true do
|
||||||
local ax2,ay2=n2.ax,n2.ay
|
if (n2==nil) break
|
||||||
for _,anchor in level:anchor_points() do
|
local anch=_sweep_radar(n2.ax,n2.ay,ax1_old,ay1_old,ax1_new,ay1_new)
|
||||||
if
|
if (anch==nil) break
|
||||||
_in_box(anchor.ax,anchor.ay,ax1_old,ay1_old,ax2,ay2) and
|
local n15={ax=anch.ax,ay=anch.ay,prev=n1,next=n2}
|
||||||
_which_side(anchor.ax,anchor.ay,ax1_old,ay1_old,ax2,ay2) !=
|
n1.next=n15
|
||||||
_which_side(anchor.ax,anchor.ay,ax1_new,ay1_new,ax2,ay2)
|
n2.prev=n15
|
||||||
then
|
n2=n15
|
||||||
local n15={ax=anchor.ax,ay=anchor.ay,prev=n1,next=n2}
|
|
||||||
n1.next = n15
|
|
||||||
n2.prev = n15
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
n1.ax=ax1_new
|
n1.ax=ax1_new
|
||||||
n1.ay=ay1_new
|
n1.ay=ay1_new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function _stepfrom(x0,x1)
|
||||||
|
local done=false
|
||||||
|
if x0==x1 then
|
||||||
|
return function()
|
||||||
|
if (done) return nil
|
||||||
|
done=true return x0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local mul=1
|
||||||
|
if (x0>x1) x0,x1,mul=-x0,-x1,-mul
|
||||||
|
local i=flr(x0)
|
||||||
|
local top=flr(x1)
|
||||||
|
return function()
|
||||||
|
if (done) return nil
|
||||||
|
i+=1
|
||||||
|
if i>top then
|
||||||
|
done = true
|
||||||
|
if (x1!=flr(x1)) return mul*x1
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
return mul*i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function _in_box(x,y,x0,y0,x1,y1)
|
function _in_box(x,y,x0,y0,x1,y1)
|
||||||
x0,x1=_mnmx(x0,x1)
|
x0,x1=_mnmx(x0,x1)
|
||||||
y0,y1=_mnmx(y0,y1)
|
y0,y1=_mnmx(y0,y1)
|
||||||
|
Loading…
Reference in New Issue
Block a user