forked from pyrex/chameleonic
Tongue anim and state machine
This commit is contained in:
parent
0821ae2bd7
commit
06e09bfc2e
@ -569,7 +569,7 @@ function player:update()
|
||||
|
||||
self.todo={{
|
||||
update=function()
|
||||
return self.rope==nil or not self.rope:casting()
|
||||
return self.rope==nil or self.rope:latched()
|
||||
end
|
||||
},{},{}}
|
||||
else
|
||||
@ -578,7 +578,7 @@ function player:update()
|
||||
end
|
||||
elseif btn(❎) then
|
||||
if self.rope!=nil then
|
||||
self.rope=nil
|
||||
self.rope:destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -718,24 +718,26 @@ function rope:new(
|
||||
src={x=src_x,y=src_y,todo={}},
|
||||
ancs={},
|
||||
dst={x=x,y=y,todo={}},
|
||||
cast={dx=dx,dy=dy},
|
||||
state={name="cast",dx=dx,dy=dy},
|
||||
latch=nil,
|
||||
latch_frame=0,
|
||||
under_destruction=false,
|
||||
}
|
||||
setmetatable(r,rope)
|
||||
return r
|
||||
end
|
||||
|
||||
function rope:casting()
|
||||
return self.cast!=nil
|
||||
function rope:latched()
|
||||
return self.state.name=="latched"
|
||||
end
|
||||
|
||||
function rope:done()
|
||||
return self.state.name=="done"
|
||||
--[[
|
||||
return self.latch_frame>=2 and (
|
||||
self.latch==nil or
|
||||
self.under_destruction
|
||||
)
|
||||
]]
|
||||
end
|
||||
|
||||
function rope:busy()
|
||||
@ -746,17 +748,26 @@ function rope:busy()
|
||||
end
|
||||
|
||||
function rope:update()
|
||||
if self.cast!=nil then
|
||||
if self.state.name=="cast" then
|
||||
self:continue_cast()
|
||||
return
|
||||
end
|
||||
self.latch_frame+=1
|
||||
elseif self.state.name=="latched" then
|
||||
self.latch_frame+=1
|
||||
if self.latch_frame>=10 then
|
||||
self.latch_frame=10
|
||||
end
|
||||
|
||||
if self.latch_frame>=10 then
|
||||
self.latch_frame=10
|
||||
self:_make_consistent()
|
||||
elseif self.state.name=="destroy" then -- destroy
|
||||
self.state.frame+=1
|
||||
if (self.state.frame>=5) self.state={name="done"}
|
||||
else --
|
||||
assert(false, "todo")
|
||||
end
|
||||
end
|
||||
|
||||
self:_make_consistent()
|
||||
function rope:destroy()
|
||||
if (self.state.name=="destroy" or self.state.name=="done") return
|
||||
self.state={name="destroy",frame=0}
|
||||
end
|
||||
|
||||
function rope:_make_consistent()
|
||||
@ -765,8 +776,9 @@ function rope:_make_consistent()
|
||||
_apply(anc,anc.todo,i)
|
||||
end
|
||||
|
||||
if (self.latch==nil) self:destroy() return
|
||||
|
||||
if
|
||||
not self.under_destruction and
|
||||
self.latch!=nil and
|
||||
self.latch.rec!=nil
|
||||
then
|
||||
@ -777,14 +789,14 @@ function rope:_make_consistent()
|
||||
|
||||
if #self.latch.rec.todo==0 then
|
||||
if self.latch.rec.dead==true then
|
||||
self.under_destruction=true
|
||||
self:destroy()
|
||||
return
|
||||
end
|
||||
for i=0,#self.ancs do
|
||||
local a0=self:_anc(i)
|
||||
local a1=self:_anc(i+1)
|
||||
if not self:_can_stretch(a0, a1) then
|
||||
self.under_destruction=true
|
||||
self:destroy()
|
||||
return
|
||||
end
|
||||
end
|
||||
@ -793,7 +805,7 @@ function rope:_make_consistent()
|
||||
end
|
||||
|
||||
function rope:continue_cast()
|
||||
local dx,dy=self.cast.dx,self.cast.dy
|
||||
local dx,dy=self.state.dx,self.state.dy
|
||||
local x0=self.src.x
|
||||
local y0=self.src.y
|
||||
local x1=x0+dx
|
||||
@ -807,10 +819,10 @@ function rope:continue_cast()
|
||||
|
||||
if latch!=nil or level:pcoll(x,y) then
|
||||
self.latch=latch
|
||||
self.cast=nil
|
||||
self.state={name="latched"}
|
||||
break
|
||||
end
|
||||
self.src={x=x,y=y,todo={}}
|
||||
self.src={x=x,y=y,todo={},dirty=true}
|
||||
end
|
||||
end
|
||||
|
||||
@ -824,17 +836,37 @@ end
|
||||
|
||||
function rope:draw()
|
||||
local points=self:_anchors_simplified()
|
||||
for i=1,(#points-1) do
|
||||
if (self.state.name=="done") return
|
||||
local perc_to_show=1.0
|
||||
if (self.state.name=="destroy") perc_to_show=(1.0-self.state.frame/5)^2
|
||||
|
||||
local len=0
|
||||
for i=1,#points-1 do
|
||||
len+=distance(points[i],points[i+1])
|
||||
end
|
||||
local len_to_show=perc_to_show*len
|
||||
|
||||
local len_cumulative=0
|
||||
for i=#points-1,1,-1 do
|
||||
local src=points[i]
|
||||
local dst=points[i+1]
|
||||
|
||||
local x,y=src.x,src.y
|
||||
local dx,dy=dst.x-x,dst.y-y
|
||||
local x,y=dst.x,dst.y
|
||||
local dx,dy=src.x-x,src.y-y
|
||||
|
||||
linefill(x,y,x+0.25*dx,y+0.25*dy,1.0,8)
|
||||
linefill(x+0.25*dx,y+0.25*dy,x+1*dx,y+1*dy,0.5,8)
|
||||
linefill(x+0.9*dx,y+0.9*dy,x+dx,y+dy,1.0,8)
|
||||
circfill(x+0.5,y+0.5,1.0,8)
|
||||
local len_here=len_to_show-len_cumulative
|
||||
local dist_base=distance_dxy(dx,dy)
|
||||
len_cumulative+=dist_base
|
||||
|
||||
if len_here>0 and dist_base>0 then
|
||||
local coef=min(len_here/dist_base,1.0)
|
||||
dx,dy=dx*coef,dy*coef
|
||||
|
||||
linefill(x,y,x+0.25*dx,y+0.25*dy,1.0,8)
|
||||
linefill(x+0.25*dx,y+0.25*dy,x+1*dx,y+1*dy,0.5,8)
|
||||
linefill(x+0.9*dx,y+0.9*dy,x+dx,y+dy,1.0,8)
|
||||
circfill(x+dx+0.5,y+dy+0.5,1.0,8)
|
||||
end
|
||||
end
|
||||
for i,p in ipairs(self.ancs) do
|
||||
rectfill(p.x-1,p.y-1,p.x+1,p.y+1,12)
|
||||
@ -886,7 +918,7 @@ function rope:drag(
|
||||
end
|
||||
|
||||
function rope:_tidy_up_gen()
|
||||
if (self.under_destruction) return
|
||||
if (not self:latched()) return
|
||||
if (not self.dirty) return
|
||||
|
||||
local settled=true
|
||||
@ -1077,6 +1109,10 @@ function sum_distance(x,y,z)
|
||||
return distance(x,y) + distance(y,z)
|
||||
end
|
||||
|
||||
function distance_dxy(dx,dy)
|
||||
return sqrt(dx*dx+dy*dy)
|
||||
end
|
||||
|
||||
function distance(p1,p2)
|
||||
local dx=p2.x-p1.x
|
||||
local dy=p2.y-p1.y
|
||||
@ -1243,7 +1279,7 @@ end
|
||||
|
||||
function rope:tug()
|
||||
self:_make_consistent()
|
||||
if (self.under_destruction) return
|
||||
if (not self:latched()) return
|
||||
self:_tug()
|
||||
self:_make_consistent()
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user