From be864f06bbf822e86dc723835453538e78504948 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Mon, 2 Jan 2023 18:00:36 -0800 Subject: [PATCH] Save a lot of tokens on segmenting the rope --- chameleonic.p8 | 97 ++++++++++++++++++++------------------------------ 1 file changed, 39 insertions(+), 58 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index 228d081..ed54ac8 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -879,7 +879,7 @@ function player:draw() if (self.orientx==1) rx+=6 if self.rope then - local rx_adj,ry_adj=self.rope:affected_src_xy(rx,ry) + local rx_adj,ry_adj=self.rope:affected_src_xy{rx,ry} if rx_adj then local drx,dry=rx_adj-rx,ry_adj-ry rx,ry=rx+drx,ry+dry @@ -891,13 +891,13 @@ function player:draw() setpal() spr(16,px+6,py-2,1,1) spr(17,px+1,py,1,1) - if (self.rope and invis_level<=0.25) pal() self.rope:draw(self.x*8+self.px+1,self.y*8+self.py+2) setpal() + if (self.rope and invis_level<=0.25) pal() self.rope:draw{self.x*8+self.px+1,self.y*8+self.py+2} setpal() spr(head,px-3,py-3,1,1) else setpal() spr(16,px-6,py-2,1,1,true) spr(17,px-1,py,1,1,true) - if (self.rope and invis_level<=0.25) pal() self.rope:draw(self.x*8+self.px+7,self.y*8+self.py+2) setpal() + if (self.rope and invis_level<=0.25) pal() self.rope:draw{self.x*8+self.px+7,self.y*8+self.py+2} setpal() spr(head,px+3,py-3,1,1,true) end pal() @@ -966,48 +966,13 @@ function rope:destroy(reelin) self.state={name="destroy",frame=0,reelin=reelin} end -function rope:affected_src_xy(artificial_px,artificial_py) - -- this is the loop from :draw but simplified - if (not self.state.reelin) return - - perc_to_show=(1.0-self.state.frame/8)^2 - local points=self:_anchors_simplified() - points[#points]={x=artificial_px,y=artificial_py} - - 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=1,#points-1 do - local src=points[i] - local dst=points[i+1] - - local x,y=dst.x,dst.y - local dx,dy=src.x-x,src.y-y - - 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) - - return x+dx-dx*coef,y+dy-dy*coef - end - end - - return points[1] -end - -function rope:draw(artificial_px,artificial_py) - local points,highlight,hypo_ops,hypo_blocks=self:_tug(true) - local n,perc_to_show,from_end = self.state.name,1.0 +function rope:_resegment(points,artificial_pxy,cb) + local n,perc_to_show,from_end=self.state.name,1.0 if (n=="done") return if (n=="cast") perc_to_show=self.state.frame/2 if (n=="destroy") perc_to_show=(1.0-self.state.frame/4)^2 if (self.state.reelin) from_end=true - + local artificial_px,artificial_py=unpack(artificial_pxy) points[#points]={x=artificial_px,y=artificial_py} local len=0 @@ -1020,10 +985,7 @@ function rope:draw(artificial_px,artificial_py) local ia,iz,istep=#points-1,1,-1 if (from_end) ia,iz,istep=1,#points-1,1 - local function colorh(ix) - color(8) - if (highlight==ix) color(12) - end + local val for i=ia,iz,istep do local src=points[i] local dst=points[i+1] @@ -1031,20 +993,39 @@ function rope:draw(artificial_px,artificial_py) local x,y=dst.x,dst.y local dx,dy=src.x-x,src.y-y - 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) + local coef=min(len_to_show/dist_base,1.0) + len_to_show-=dist_base + dx,dy=dx*coef,dy*coef - if from_end then - x,y=x+dx-dx*coef,y+dy-dy*coef - end - dx,dy=dx*coef,dy*coef + if (from_end) x,y=src.x-dx,src.y-dy + local v0,v1=cb(x,y,dx,dy,i) + if (coef<1) return v0,v1 + end +end + +function rope:affected_src_xy(artificial_pxy) + if (not self.state.reelin) return + + return self:_resegment( + self:_anchors_simplified(),artificial_pxy, + function(x,y) return x,y end + ) +end + +function rope:draw(artificial_pxy) + local points,highlight,hypo_ops,hypo_blocks=self:_tug(true) + + local function colorh(ix) + color(8) + if (highlight==ix) color(12) + end + + self:_resegment(points,artificial_pxy, + function(x,y,dx,dy,i) colorh(i) - local function lf(d0,d1,w) linefill(x+d0*dx,y+d0*dy,x+d1*dx,y+d1*dy,w) end @@ -1054,11 +1035,11 @@ function rope:draw(artificial_px,artificial_py) lf(0.9,1,1.0) circfill(x+dx+0.5,y+dy+0.5,1.0) end - end + ) -- draw latch local l=self.latch - if l and l.rec and (perc_to_show>=1.0 or from_end) then + if l and l.rec and (self.state.reelin or self:latched()) then local function rfsplit(x) rectfill(unpack(split(x))) end local ldx,ldy=l.dx,l.dy colorh(0) @@ -1073,7 +1054,7 @@ function rope:draw(artificial_px,artificial_py) -- hypothetical local time=t()-self.flicker_t - if n=="latched" and time>0 and not level:busy() then + if self:latched() and time>0 and not level:busy() then if time%0.5>0.25 then for o in all(hypo_ops) do local mx0,my0,dmx,dmy=unpack(o) @@ -1620,7 +1601,7 @@ function rope:_tug(hypothetically) end end - if (hypothetically) return ancs,0,{},blocks + if (hypothetically) return ancs,32767,{},blocks -- invalid return end