diff --git a/chameleonic.p8 b/chameleonic.p8 index 3401e84..ae900a5 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -234,10 +234,10 @@ function level:reinit(n) self.ix=n self.todo={} self.bigx,self.bigy=n%8,n\8 + self.dirty=false self:load_dynobjs() - self:recollide() - self:reanchor(true) + self:recollide_reanchor() self:spawn_exit() end @@ -309,10 +309,12 @@ function level:update() end for cix in all(remove) do self._crates[cix]=nil + self.dirty=true end - if #remove>0 then - self:recollide() - self:reanchor() + + if self.dirty then + self:recollide_reanchor() + self.dirty=false end end @@ -344,7 +346,7 @@ function level:load_dynobjs() end end -function level:recollide() +function level:recollide_reanchor() self._coll={} for mx=0,15 do for my=0,15 do @@ -354,9 +356,7 @@ function level:recollide() self._crates[mxy] end end -end -function level:reanchor() local anch_new={} for dxy in all{{-1,-1},{1,-1},{-1,1},{1,1}} do local dx,dy=unpack(dxy) @@ -575,8 +575,7 @@ function level:tug_crate(mx0,my0,dmx,dmy) local px1,py1=mx1*8,my1*8 existing.todo={ {px=px1+dmx,py=py1+dmy,mx=mx1,my=my1,update=function() - self:recollide() - self:reanchor() + self.dirty=true return true end}, {px=px1,py=py1} @@ -1007,16 +1006,11 @@ function rope:draw(artificial_px,artificial_py) local n2=n1.next if n0!=nil and n2!=nil then if anch then - local _,_,_,adx,ady=would_stick(anch,n0.ax,n0.ay,n1.ax,n1.ay,n2.ax,n2.ay) - assert(adx==-1 or adx==0 or adx==1) - assert(ady==-1 or ady==0 or ady==1) - --assert(not (adx==0 and ady==0)) + local _,_,_=would_stick(anch,n0.ax,n0.ay,n1.ax,n1.ay,n2.ax,n2.ay) local c=3 if (anch.dropped) c=4 rectfill(x+2,y+2,x+4,y+4,c) - pset(x+adx*2,y,9) - pset(x,y+ady*2,9) else rectfill(x+2,y+2,x+4,y+4,2) end @@ -1163,33 +1157,35 @@ function rope:_check_sane() end function would_stick(anchor,x0,y0,x1,y1,x2,y2) - if (x1==nil or y1==nil) x1,y1=anchor.ax,anchor.ay - - local dx=x2-x0 - local dy=y2-y0 + x1,y1=x1 or anchor.ax,y1 or anchor.ay + local dx,dy=x2-x0,y2-y0 if (x1==x0 and y1==y0) return if (x1==x2 and y1==y2) return - local adx,ady - local x1_new,y1_new - if abs(dx)>abs(dy) then - if (x0>x2) dx,x0,y0,x2,y2=-dx,x2,y2,x0,y0 - local dprop=(x1-x0)/dx - x1_new,y1_new=x1,y0+dprop*(y2-y0) - ady=sgn0(y1_new-y1) - adx=sgn0(y0-y2)*ady - else - if (y0>y2) dy,x0,y0,x2,y2=-dy,x2,y2,x0,y0 - local dprop=(y1-y0)/dy - x1_new,y1_new=x0+dprop*(x2-x0),y1 - adx=sgn0(x1_new-x1) - ady=sgn0(x0-x2)*adx + local function switch_ends() + dx,dy,x0,y0,x2,y2=-dx,-dy,x2,y2,x0,y0 end - local wouldnt=anchor==nil or (anchor.adx!=adx or anchor.ady!=ady) + local function signs(douter,dinner) + local adb=sgn0(dinner) + return -sgn0(douter)*adb,adb + end - return not wouldnt,x1_new,y1_new,adx,ady + local adx,ady,x1_new,y1_new + if abs(dx)>abs(dy) then + if (x0>x2) switch_ends() + x1_new,y1_new=x1,y0+(x1-x0)/dx*dy + adx,ady=signs(dy,y1_new-y1) + else + if (y0>y2) switch_ends() + x1_new,y1_new=x0+(y1-y0)/dy*dx,y1 + ady,adx=signs(dx,x1_new-x1) + end + + return + anchor and anchor.adx==adx and anchor.ady==ady, + x1_new,y1_new end function rope:experience_anchor_moves(moves)