From a27cc2e6ef41e626ca415b770bb0d24cdf399481 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Wed, 21 Dec 2022 17:50:06 -0800 Subject: [PATCH 01/20] Re-center rope --- chameleonic.p8 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index 1396654..cc1bc96 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -760,7 +760,7 @@ function player:update() self.rope=rope:new( x+0.5-dx*0.5,y+0.5-dy*0.5, - self.x+0.5,self.y+0.1, + self.x+0.5,self.y+0.5, level:get_latch(dx,dy,x*8,y*8) ) @@ -781,7 +781,7 @@ function player:update() if self.rope then self.rope:update() - self.rope:drag_dst(self.x+self.px/8+0.5,self.y+self.py/8+0.1) + self.rope:drag_dst(self.x+self.px/8+0.5,self.y+self.py/8+0.5) local tdx,tdy=self.rope:tug_orientxy() if (tdx!=0) self.orientx=tdx -- 2.34.1 From 672f1b395112fc679c19e64afc1bbceed9037009 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Wed, 21 Dec 2022 18:11:19 -0800 Subject: [PATCH 02/20] Hint text for certain levels --- chameleonic.p8 | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index cc1bc96..9c28c88 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -864,13 +864,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(-2,-1) 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(2,-1) 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() @@ -946,14 +946,14 @@ function rope:destroy() self.state={name="destroy",frame=0} end -function rope:draw(artificial_dx,artificial_dy) +function rope:draw(artificial_px,artificial_py) local points,highlight=self:_tug(true) if (self.state.name=="done") return local perc_to_show=1.0 if (self.state.name=="cast") perc_to_show=self.state.frame/2 if (self.state.name=="destroy") perc_to_show=(1.0-self.state.frame/5)^2 - points[#points]={x=points[#points].x+artificial_dx,y=points[#points].y+artificial_dy} + points[#points]={x=artificial_px,y=artificial_py} local len=0 for i=1,#points-1 do @@ -1622,6 +1622,28 @@ function wrongbleep:adequately_warned(duration) end +-->8 +-- text +level_text={by_lvl={}} +add(real_modules,level_text) +level_text_raw={ + "9`9`11`\f7\#0press 🅾️ to mlem & unmlem", + "9`33`17`\f7\#0❎ to yoink" +} +function level_text:init() + for i=0,32 do level_text.by_lvl[i]={} end + for row in all(level_text_raw) do + if row then + lvl,x,y,s=unpack(split(row,"`")) + add(level_text.by_lvl[lvl],{x,y,s}) + end + end +end +function level_text:draw() + for xys in all(level_text.by_lvl[level.ix]) do + print(xys[3],xys[1],xys[2],6) + end +end __gfx__ 000030000000002200003000000cc0cc0cccccccccccccccccccccccccccccccc0bb0000000000000000000000000000dddddddd000000000005000000000000 003333300000332200333330000cc0cc0000cc0000000000000000000cc0000000bb0bb0bbbb0bbbbb0bbbbb0bbb0000dddddddd000000000000500000000000 -- 2.34.1 From 6658f71ba24de33125aaba278fd7e467ae5ac3c6 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Wed, 21 Dec 2022 19:12:21 -0800 Subject: [PATCH 03/20] Correct when the rope crashes into the other side of something --- chameleonic.p8 | 110 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 87 insertions(+), 23 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index 9c28c88..8abe8a4 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -450,7 +450,7 @@ function level:reanchor() local old=anch_old[k] if old then anch_new[k]=old - old.ax,old.ay,old.adx,old.ady=new.ax,new.ay,new.adx,new.ady + old.ax_old,old.ay_old,old.ax,old.ay,old.adx,old.ady=old.ax,old.ay,new.ax,new.ay,new.adx,new.ady old.dropped=nil end end @@ -459,6 +459,17 @@ function level:reanchor() for k,_ in pairs(self._anch) do add(self._anch_keys,{key=k}) end + shellsort(self._anch_keys) + for point in self:anchor_points() do + if point.ax_old!=nil then + if (player.rope!=nil) player.rope:be_pushed_by(point,point.ax_old,point.ay_old) + point.ax_old=nil + point.ay_old=nil + end + end + for point in self:anchor_points() do + assert(not point.dropped) + end if (player.rope!=nil) player.rope:relax() end @@ -617,13 +628,13 @@ function level:can_move( if player.rope then local chk=false if dmx==0 and dmy==-1 then - chk=player.rope:collide_mrect(mx0,my0-1,1,2,exclude_src,exclude_dst) + chk=player.rope:collide_mrect(mx0+0.4,my0-0.8,0.2,1.6,exclude_src,exclude_dst) elseif dmx==0 and dmy==1 then - chk=player.rope:collide_mrect(mx0,my0,1,2,exclude_src,exclude_dst) + chk=player.rope:collide_mrect(mx0+0.4,my0+0.2,0.2,1.6,exclude_src,exclude_dst) elseif dmx==-1 and dmy==0 then - chk=player.rope:collide_mrect(mx0-1,my0,2,1,exclude_src,exclude_dst) + chk=player.rope:collide_mrect(mx0-0.8,my0+0.4,1.6,0.2,exclude_src,exclude_dst) elseif dmx==1 and dmy==0 then - chk=player.rope:collide_mrect(mx0,my0,2,1,exclude_src,exclude_dst) + chk=player.rope:collide_mrect(mx0+0.2,my0+0.4,1.6,0.2,exclude_src,exclude_dst) end if (chk) return false @@ -781,7 +792,10 @@ function player:update() if self.rope then self.rope:update() - self.rope:drag_dst(self.x+self.px/8+0.5,self.y+self.py/8+0.5) + local rx=self.x+self.px/8+0.5 + local ry=self.y+self.py/8+0.5 + -- do the hokey pokey to work out kinks in the rope + self.rope:drag_dst(rx,ry) local tdx,tdy=self.rope:tug_orientxy() if (tdx!=0) self.orientx=tdx @@ -1030,7 +1044,7 @@ function rope:draw(artificial_px,artificial_py) --assert(not (adx==0 and ady==0)) local c=3 - if (n1.associated_with.dropped) c=8 + if (n1.associated_with.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) @@ -1083,6 +1097,20 @@ function rope:relax() n=n.next end + local n0=self.src + while true do + local n1=n0.next + if (n1==nil) break + local n2=n1.next + + if n0.ax==n1.ax and n0.ay==n1.ay then + n0.next=n2 + n2.prev=n0 + else + n0=n0.next + end + end + local n0=self.src while true do if (n0==nil) return @@ -1187,7 +1215,6 @@ end function would_stick(x0,y0,anchor,x2,y2) local x1,y1=anchor.ax,anchor.ay - if (x0>x2) x0,y0,x2,y2=x2,y2,x0,y0 local dx=x2-x0 local dy=y2-y0 @@ -1195,6 +1222,7 @@ function would_stick(x0,y0,anchor,x2,y2) 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) @@ -1202,25 +1230,66 @@ function would_stick(x0,y0,anchor,x2,y2) if (y0>y2) adx=ady if (y0y2) 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=0 - if (y0>y2) ady=adx - if (y0x2) ady=adx + if (x0"..tostring(n05.associated_with).."->"..tostring(n1.associated_with)) + else + n0=n0.next + end + end +end + function rope:_drag(n1,ax1_new,ay1_new) local function _sweep_radar(ax_pivot,ay_pivot,ax_far0,ay_far0,ax_far1,ay_far1) if (ax_far0==ax_far1 and ay_far0==ay_far1) return nil - local function crossed(x,y) - return x!=y - end if ax_far0==ax_far1 then local ax_far=ax_far0 @@ -1235,8 +1304,8 @@ function rope:_drag(n1,ax1_new,ay1_new) not (anchor.ax==ax_far1 and anchor.ay==ay_far1) and (ax0<=anchor.ax and anchor.ax<=ax1) and would_stick(ax_pivot,ay_pivot,anchor,ax_far,ay_far_new) and - crossed( - _which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far,ay_far_old), + ( + _which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far,ay_far_old) != _which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far,ay_far_new) ) then @@ -1258,8 +1327,8 @@ function rope:_drag(n1,ax1_new,ay1_new) not (anchor.ax==ax_far1 and anchor.ay==ay_far1) and would_stick(ax_pivot,ay_pivot,anchor,ax_far_new,ay_far) and (ay0<=anchor.ay and anchor.ay<=ay1) and - crossed( - _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_old,ay_far) != _which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far_new,ay_far) ) then @@ -1345,11 +1414,6 @@ function rope:collide_mrect(mx0,my0,mw,mh,exclude_src,exclude_dst) local mx1,my1=mx0+mw,my0+mh local n0=self.src - mx0+=0.4 - my0+=0.4 - mx1-=0.4 - my1-=0.4 - while true do local n1=n0.next if (n1==nil) return false -- 2.34.1 From e2334f55f7b462ae1c9c1f37769c7decfe5cddb7 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Wed, 21 Dec 2022 19:54:09 -0800 Subject: [PATCH 04/20] Allow reeling in --- chameleonic.p8 | 100 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 10 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index 8abe8a4..2ff44ac 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -788,10 +788,18 @@ function player:update() end end + if self.rope then + self.rope:update() + end _apply(self,self.todo) if self.rope then self.rope:update() + if self.rope:done_reeling() then + self.x=self.rope.latch.rec.mx+self.rope.latch.dx + self.y=self.rope.latch.rec.my+self.rope.latch.dy + end + local rx=self.x+self.px/8+0.5 local ry=self.y+self.py/8+0.5 -- do the hokey pokey to work out kinks in the rope @@ -874,6 +882,18 @@ function player:draw() end end + local rx,ry=self.x*8+self.px+1,self.y*8+self.py+2 + if (self.orientx==1) rx+=6 + + if self.rope then + local rx_adj,ry_adj=self.rope:affected_src_xy(rx,ry) + if rx_adj!=nil then + local drx,dry=rx_adj-rx,ry_adj-ry + rx,ry=rx+drx,ry+dry + px,py=px+drx,py+dry + end + end + if self.orientx==-1 then setpal() spr(16,px+6,py-2,1,1) @@ -923,6 +943,10 @@ function rope:done() return self.state.name=="done" end +function rope:done_reeling() + return self.state.name=="done" and self.state.reelin +end + function rope:update() if self.state.name=="cast" then self.state.frame+=1 @@ -949,23 +973,59 @@ function rope:update() elseif self.state.name=="destroy" then -- destroy self.state.frame+=1 - if (self.state.frame>=5) self.state={name="done"} + if (self.state.frame>=5) self.state={name="done",reelin=self.state.reelin} else -- done state end end -function rope:destroy() +function rope:destroy(reelin) if (self.state.name=="destroy" or self.state.name=="done") return - self.state={name="destroy",frame=0} + 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=self:_tug(true) if (self.state.name=="done") return local perc_to_show=1.0 + local from_end=false if (self.state.name=="cast") perc_to_show=self.state.frame/2 - if (self.state.name=="destroy") perc_to_show=(1.0-self.state.frame/5)^2 + if (self.state.name=="destroy") perc_to_show=(1.0-self.state.frame/8)^2 + if (self.state.reelin) from_end=true points[#points]={x=artificial_px,y=artificial_py} @@ -976,7 +1036,9 @@ function rope:draw(artificial_px,artificial_py) local len_to_show=perc_to_show*len local len_cumulative=0 - for i=#points-1,1,-1 do + local ia,iz,istep=#points-1,1,-1 + if (from_end) ia,iz,istep=1,#points-1,1 + for i=ia,iz,istep do local src=points[i] local dst=points[i+1] @@ -985,11 +1047,17 @@ function rope:draw(artificial_px,artificial_py) local len_here=len_to_show-len_cumulative local dist_base=distance_dxy(dx,dy) - len_cumulative+=dist_base + 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 + + if from_end then + x,y=x+dx-dx*coef,y+dy-dy*coef + dx,dy=dx*coef,dy*coef + else + dx,dy=dx*coef,dy*coef + end local color=8 if (highlight==i) color=12 @@ -1002,7 +1070,7 @@ function rope:draw(artificial_px,artificial_py) end -- draw latch - if self.latch!=nil and self.latch.rec and perc_to_show>=1.0 then + if self.latch!=nil and self.latch.rec and (perc_to_show>=1.0 or from_end) then local x,y=self.latch.rec.px,self.latch.rec.py local ldx,ldy=self.latch.dx,self.latch.dy local color=8 @@ -1141,7 +1209,7 @@ function rope:relax() end function rope:_check_sane() - if (self.state.name!="latched") return true + if (not self:latched()) return true if (level:busy()) return true local n0=self.src @@ -1502,6 +1570,18 @@ function rope:_tug(hypothetically) end local latch=self.latch + if latch!=nil and latch.el=="eyehook" then + if (hypothetically) return ancs,0 + player.todo={{ + update=function(s) + if s.rope==nil or s.rope:done() then + return true + end + end + }} + self:destroy(true) + return true + end if latch!=nil and latch.el=="crate" then local dmx,dmy= sgn0(latch.dx), @@ -1888,7 +1968,7 @@ __map__ 0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 0c000000000044000c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 0c0000000000000000000000000000000c00000000000000000000000000000c000000000000000000000000000000000e00000000000e0e0e0e0000000000000e000000000e000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 -0c00000000001c0000000000000000000000000000000000000000000000000c000000000000000000000000000000000e00000000000000000e0000000000000e000000000e000e00000000000000000e0000000000000000000000000000000e0000000000000e0e000000000000000e00000000000e0e0e0e000000000000 +3d1c000000001c0000000000000000000000000000000000000000000000000c000000000000000000000000000000000e00000000000000000e0000000000000e000000000e000e00000000000000000e0000000000000000000000000000000e0000000000000e0e000000000000000e00000000000e0e0e0e000000000000 0c0000000000000000000000000000410000000000000000000000000000000c0000000000000e0e0e000000000000000e00000000000000000e0000000000000e000000000e000e00000000000000000e00000000000e0e0e000000000000000e00000000000e0000000000000000000e00000000000000000e000000000000 0c000000000000000c0c0c0c0c0c0c0c0c00000000000020210000000000000c00000000000e00000e0e0000000000000e0000000000000e0e0e0000000000000e000000000e0e0e0e0e0000000000000e00000000000e0000000000000000000e00000000000e0e0e000000000000000e000000000000000e00000000000000 0c0c0c0c0c0c00000000000c0c0c0c0c0c00000000000030310000000000000c000000000000000e0e000000000000000e00000000000000000e0000000000000e0000000000000e00000000000000000e00000000000e0e0e000000000000000e00000000000e00000e0000000000000e0000000000000e0000000000000000 -- 2.34.1 From 4072499c4c671628fed79fc4ae35c67dd846ae42 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Wed, 21 Dec 2022 21:37:26 -0800 Subject: [PATCH 05/20] This case shouldn't need to be special --- chameleonic.p8 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/chameleonic.p8 b/chameleonic.p8 index 2ff44ac..40cb8f0 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -1287,6 +1287,12 @@ function would_stick(x0,y0,anchor,x2,y2) local dx=x2-x0 local dy=y2-y0 + -- there is no reason for an acute angle to stick around in this world + local ang0=atan2(x2-x1,y2-y1) + local ang2=atan2(x0-x1,y0-y1) + local diff=abs((ang0-ang2 + 0.5)%1-0.5) + if (diff<0.25) return false,x0,y0,0,0 + local adx,ady local x1_new,y1_new if abs(dx)>abs(dy) then -- 2.34.1 From 197c68dd88d133ab5abdb3914e53def306122b2b Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Wed, 21 Dec 2022 21:40:16 -0800 Subject: [PATCH 06/20] Actually, that special case causes unnecessary rope shortening --- chameleonic.p8 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chameleonic.p8 b/chameleonic.p8 index 40cb8f0..0b606e6 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -1288,10 +1288,12 @@ function would_stick(x0,y0,anchor,x2,y2) local dy=y2-y0 -- there is no reason for an acute angle to stick around in this world + --[[ local ang0=atan2(x2-x1,y2-y1) local ang2=atan2(x0-x1,y0-y1) local diff=abs((ang0-ang2 + 0.5)%1-0.5) if (diff<0.25) return false,x0,y0,0,0 + ]]-- local adx,ady local x1_new,y1_new -- 2.34.1 From 791b49934f78afc4c4b91a86bdad2e432b1af5d1 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Wed, 21 Dec 2022 21:55:21 -0800 Subject: [PATCH 07/20] Add another case I missed --- chameleonic.p8 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/chameleonic.p8 b/chameleonic.p8 index 0b606e6..3de36dc 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -1331,8 +1331,11 @@ function rope:be_pushed_by(anchor,ax_old,ay_old) local nx1,ny1=n1.ax,n1.ay if + (ax_new==ax_old and nx0<=anchor.ax and anchor.ax<=nx1) and + (ay_new==ay_old and ny0<=anchor.ay and anchor.ay<=ny1) and not (anchor.ax==nx0 and anchor.ay==ny0) and not (anchor.ax==nx1 and anchor.ay==ny1) and + (_which_side(ax_old,ay_old,nx0,ny0,nx1,ny1)!= _which_side(ax_new,ay_new,nx0,ny0,nx1,ny1) ) and would_stick(nx0,ny0,anchor,nx1,ny1) -- 2.34.1 From d782f6eb14ed648a29b46e61dadd5e828b99cf34 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Thu, 22 Dec 2022 11:25:31 -0800 Subject: [PATCH 08/20] Fix another rope bug --- chameleonic.p8 | 126 +++++++++++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 68 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index 3de36dc..adb0f58 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -1087,7 +1087,6 @@ function rope:draw(artificial_px,artificial_py) end -- debug - --[[ local n1=self.src local sy=0 while true do @@ -1134,7 +1133,6 @@ function rope:draw(artificial_px,artificial_py) pset(x+p.adx,y,11) pset(x,y+p.ady,11) end - ]] end function rope:drag_dst(x,y) @@ -1153,18 +1151,6 @@ function rope:drag(n1,ax_new,ay_new) end function rope:relax() - local n=self.src - - while true do - if (n==nil) break - - if (n.associated_with) then - self:_drag(n,n.associated_with.ax,n.associated_with.ay) - end - - n=n.next - end - local n0=self.src while true do local n1=n0.next @@ -1173,7 +1159,7 @@ function rope:relax() if n0.ax==n1.ax and n0.ay==n1.ay then n0.next=n2 - n2.prev=n0 + if (n2!=nil) n2.prev=n0 else n0=n0.next end @@ -1193,9 +1179,14 @@ function rope:relax() local x1,y1=n1.ax,n1.ay local x2,y2=n2.ax,n2.ay + if x1!=n1.associated_with.ax or y1!=n1.associated_with.ay then + -- printh("dragging home: "..tostring{n1.ax,n1.ay}.."->"..tostring(n1.associated_with)) + self:_drag(n1,n1.associated_with.ax,n1.associated_with.ay) + end + local would,x1_new,y1_new=would_stick(x0,y0,n1.associated_with,x2,y2) if not would and not (n1.ax==x1_new and n1.ay==y1_new) then - --printh("relaxing: "..tostring(n0.associated_with).."->"..tostring(n1.associated_with).."->"..tostring(n2.associated_with)) + -- printh("relaxing: "..tostring(n0.associated_with).."->"..tostring(n1.associated_with).."->"..tostring(n2.associated_with)) self:_drag(n1,x1_new,y1_new) n0=n1.prev n2=n1.next @@ -1379,7 +1370,7 @@ function rope:_drag(n1,ax1_new,ay1_new) for anchor in level:anchor_points() do if not (anchor.ax==ax_pivot and anchor.ay==ay_pivot) and - not (anchor.ax==ax_far0 and anchor.ay==ay_far0) and + -- not (anchor.ax==ax_far0 and anchor.ay==ay_far0) and not (anchor.ax==ax_far1 and anchor.ay==ay_far1) and (ax0<=anchor.ax and anchor.ax<=ax1) and would_stick(ax_pivot,ay_pivot,anchor,ax_far,ay_far_new) and @@ -1402,7 +1393,7 @@ function rope:_drag(n1,ax1_new,ay1_new) for anchor in level:anchor_points() do if not (anchor.ax==ax_pivot and anchor.ay==ay_pivot) and - not (anchor.ax==ax_far0 and anchor.ay==ay_far0) and + -- not (anchor.ax==ax_far0 and anchor.ay==ay_far0) and not (anchor.ax==ax_far1 and anchor.ay==ay_far1) and would_stick(ax_pivot,ay_pivot,anchor,ax_far_new,ay_far) and (ay0<=anchor.ay and anchor.ay<=ay1) and @@ -1429,7 +1420,7 @@ function rope:_drag(n1,ax1_new,ay1_new) 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,associated_with=anch,prev=n0,next=n1} - --printh("creating post: "..tostring(n0.associated_with).."->"..tostring(n05.associated_with).."->"..tostring(n1.associated_with)) + -- printh("creating pre: "..tostring(n0.associated_with).."->"..tostring(n05.associated_with).."->"..tostring(n1.associated_with)) n0.next=n05 n1.prev=n05 n0=n05 @@ -1441,7 +1432,7 @@ function rope:_drag(n1,ax1_new,ay1_new) local anch=_sweep_radar(n2.ax,n2.ay,ax1_old,ay1_old,ax1_new,ay1_new) if (anch==nil) break local n15={ax=anch.ax,ay=anch.ay,associated_with=anch,prev=n1,next=n2} - --printh("creating post: "..tostring(n1.associated_with).."->"..tostring(n15.associated_with).."->"..tostring(n2.associated_with)) + -- printh("creating post: "..tostring(n1.associated_with).."->"..tostring(n15.associated_with).."->"..tostring(n2.associated_with)) n1.next=n15 n2.prev=n15 n2=n15 @@ -1503,31 +1494,30 @@ function rope:collide_mrect(mx0,my0,mw,mh,exclude_src,exclude_dst) if (nd==nil) return false end + local x1,y1,x2,y2=n0.ax,n0.ay,n1.ax,n1.ay + local function _line_line(x3,y3,x4,y4) + local denom=((y4-y3)*(x2-x1)-(x4-x3)*(y2-y1)) + + local ua= + ((x4-x3)*(y1-y3)-(y4-y3)*(x1-x3))/denom + if (ua<0 or ua>1) return false + + local ub= + ((x2-x1)*(y1-y3)-(y2-y1)*(x1-x3))/denom + if (ub<0 or ub>1) return false + + return true + end + + if exclude_src<=0 then - if (_line_line(n0.ax,n0.ay,n1.ax,n1.ay,mx0,my0,mx1,my0)) return true - if (_line_line(n0.ax,n0.ay,n1.ax,n1.ay,mx0,my0,mx0,my1)) return true - if (_line_line(n0.ax,n0.ay,n1.ax,n1.ay,mx0,my1,mx1,my1)) return true - if (_line_line(n0.ax,n0.ay,n1.ax,n1.ay,mx1,my0,mx1,my1)) return true + if (_line_line(mx0,my0,mx1,my0) or _line_line(mx0,my0,mx0,my1) or _line_line(mx0,my1,mx1,my1) or _line_line(mx1,my0,mx1,my1)) return true end exclude_src-=1 n0=n1 end end -function _line_line(x1,y1,x2,y2,x3,y3,x4,y4) - local denom=((y4-y3)*(x2-x1)-(x4-x3)*(y2-y1)) - - local ua= - ((x4-x3)*(y1-y3)-(y4-y3)*(x1-x3))/denom - if (ua<0 or ua>1) return false - - local ub= - ((x2-x1)*(y1-y3)-(y2-y1)*(x1-x3))/denom - if (ub<0 or ub>1) return false - - return true -end - -->8 -- moved here because it's complicated @@ -1728,20 +1718,20 @@ function rope:_anchors_simplified() x=flr(a.ax*8+0.5),y=flr(a.ay*8+0.5), ax=a.ax,ay=a.ay } - if a.associated_with then - if (a.associated_with.adx==1) point.x-=1 - if (a.associated_with.ady==1) point.y-=1 - elseif a.prev==nil and self.latch then - if (self.latch.ax_offset<0) point.x-=1 - if (self.latch.ay_offset<0) point.y-=1 + local aw=a.associated_with + local l=self.latch + if aw then + if (aw.adx==1) point.x-=1 + if (aw.ady==1) point.y-=1 + elseif a.prev==nil and l then + if (l.ax_offset<0) point.x-=1 + if (l.ay_offset<0) point.y-=1 end - if #points<=1 then + local p0,p1=points[#points-1],points[#points] + if p0==nil then add(points,point) - elseif abs( - _slope(points[#points-1],points[#points])- - _slope(points[#points],point) - )==0 then -- epsilon? + elseif _slope(p0,p1)==_slope(p1,point) then -- epsilon? points[#points]=point else add(points,point) @@ -1789,14 +1779,14 @@ function level_text:init() for i=0,32 do level_text.by_lvl[i]={} end for row in all(level_text_raw) do if row then - lvl,x,y,s=unpack(split(row,"`")) - add(level_text.by_lvl[lvl],{x,y,s}) + lvlxys=split(row,"`") + add(level_text.by_lvl[lvlxys[1]],lvlxys) end end end function level_text:draw() for xys in all(level_text.by_lvl[level.ix]) do - print(xys[3],xys[1],xys[2],6) + print(xys[4],xys[2],xys[3],6) end end __gfx__ @@ -1974,22 +1964,22 @@ __gff__ 000000000808080808080808c00000000000000008080808080808080000000040400000080808080808080800000000404000000808080808080808c0c0c0c000000000080808080808080800000000000000000808080808080808000000000000000008080808080808080000000000000000080808080808080800000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 __map__ -0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e -0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 -0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 -0c000000000044000c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 -0c0000000000000000000000000000000c00000000000000000000000000000c000000000000000000000000000000000e00000000000e0e0e0e0000000000000e000000000e000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 -3d1c000000001c0000000000000000000000000000000000000000000000000c000000000000000000000000000000000e00000000000000000e0000000000000e000000000e000e00000000000000000e0000000000000000000000000000000e0000000000000e0e000000000000000e00000000000e0e0e0e000000000000 -0c0000000000000000000000000000410000000000000000000000000000000c0000000000000e0e0e000000000000000e00000000000000000e0000000000000e000000000e000e00000000000000000e00000000000e0e0e000000000000000e00000000000e0000000000000000000e00000000000000000e000000000000 -0c000000000000000c0c0c0c0c0c0c0c0c00000000000020210000000000000c00000000000e00000e0e0000000000000e0000000000000e0e0e0000000000000e000000000e0e0e0e0e0000000000000e00000000000e0000000000000000000e00000000000e0e0e000000000000000e000000000000000e00000000000000 -0c0c0c0c0c0c00000000000c0c0c0c0c0c00000000000030310000000000000c000000000000000e0e000000000000000e00000000000000000e0000000000000e0000000000000e00000000000000000e00000000000e0e0e000000000000000e00000000000e00000e0000000000000e0000000000000e0000000000000000 -0c00000000000c0c004f000c0c0c0c0c0c00000000000000000000000000000c0000000000000e0e00000000000000000e00000000000e0e0e0e0000000000000e0000000000000e00000000000000000e000000000000000e000000000000000e0000000000000e0e000000000000000e0000000000000e0000000000000000 -0c00000c4f00000000000000000000120100000000000000000000000000000c00000000000e0e0e0e0e0000000000000e0000000000000000000000000000000e0000000000000e00000000000000000e00000000000e0e0e000000000000000e0000000000000000000000000000000e000000000000000000000000000000 -3d0000000000003f0c000c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 -0c0000000000000000000c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 -010000000000000c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 -0c0c0c0c00000c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 -0c0c0c0c00410c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c000000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 +0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e +0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c0c00000000000000000000000000000c0e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 +0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c0c0000000000000c001c1c000c0c000c0e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 +0c000000000044000c0c0c0c0c0c0c0c0c00000000000000000000000000000c0c0000000000000000000000000c000c0e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 +0c0000000000000000000000000000000c00000000000000000000000000000c0c00004f0c0c0000000c000000001c120e00000000000e0e0e0e0000000000000e000000000e000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 +3d1c000000001c0000000000000000000000000000000000000000000000000c3d000c000c0c0000003f0c0c0000000c0e00000000000000000e0000000000000e000000000e000e00000000000000000e0000000000000000000000000000000e0000000000000e0e000000000000000e00000000000e0e0e0e000000000000 +0c0000000000000000000000000000410000000000000000000000000000000c0c000c0000000000000000000000000c0e00000000000000000e0000000000000e000000000e000e00000000000000000e00000000000e0e0e000000000000000e00000000000e0000000000000000000e00000000000000000e000000000000 +0c000000000000000c0c0c0c0c0c0c0c0c00000000000020210000000000000c01000c0c00000000000c0c004f00000c0e0000000000000e0e0e0000000000000e000000000e0e0e0e0e0000000000000e00000000000e0000000000000000000e00000000000e0e0e000000000000000e000000000000000e00000000000000 +0c0c0c0c0c0c00000000000c0c0c0c0c0c00000000000030310000000000000c0c0000000000000c00000c000000000c0e00000000000000000e0000000000000e0000000000000e00000000000000000e00000000000e0e0e000000000000000e00000000000e00000e0000000000000e0000000000000e0000000000000000 +0c00000000000c0c004f000c0c0c0c0c0c00000000000000000000000000000c0c00004f0000000c0c000c0000000c0c0e00000000000e0e0e0e0000000000000e0000000000000e00000000000000000e000000000000000e000000000000000e0000000000000e0e000000000000000e0000000000000e0000000000000000 +0c00000c4f00000000000000000000120100000000000000000000000000000c0c00000000000000000000000000000c0e0000000000000000000000000000000e0000000000000e00000000000000000e00000000000e0e0e000000000000000e0000000000000000000000000000000e000000000000000000000000000000 +3d0000000000003f0c000c0c0c0c0c0c0c00000000000000000000000000000c0c00000c00000000000000000000000c0e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 +0c0000000000000000000c0c0c0c0c0c0c00000000000000000000000000000c0c000c0c0c0000000c0c0c004f00000c0e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 +010000000000000c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c0c00000c00000000000000000000000c0e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 +0c0c0c0c00000c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c0c00000000001c00000000000000000c0e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 +0c0c0c0c00410c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e 0c00000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0e0000000000000000000000000000000e000000000000000000000000000000 0c004f000000000c001c1c000c0c000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c00000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c3e0c0c0c0c0c0e0000000000000000000000000000000e000000000000000000000000000000 -- 2.34.1 From f3a0b04cc4f2cb971546d7a0e58a8053576c4b9e Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Thu, 22 Dec 2022 18:30:05 -0800 Subject: [PATCH 09/20] Golf linefill --- chameleonic.p8 | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index adb0f58..4dbf81a 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -53,21 +53,19 @@ function linefill(ax,ay,bx,by,r,c) local dx,dy=bx-ax,by-ay -- avoid overflow -- credits: https://www.lexaloffle.com/bbs/?tid=28999 - local d=max(abs(dx),abs(dy)) - local n=min(abs(dx),abs(dy))/d + local n,d=_mnmx(abs(dx),abs(dy)) + n/=d d*=sqrt(n*n+1) if(d<0.001) return local ca,sa=dx/d,-dy/d -- polygon points - local s={ - {0,-r},{d,-r},{d,r},{0,r} - } - local u,v,spans=s[4][1],s[4][2],{} - local x0,y0=ax+u*ca+v*sa,ay-u*sa+v*ca + local s={{0,-r},{d,-r},{d,r},{0,r}} + local spans={} + local function calcxy(u,v) return ax+u*ca+v*sa,ay-u*sa+v*ca end + local x0,y0=calcxy(0,r) for i=1,4 do - local u,v=s[i][1],s[i][2] - local x1,y1=ax+u*ca+v*sa,ay-u*sa+v*ca + local x1,y1=calcxy(unpack(s[i])) local _x1,_y1=x1,y1 if(y0>y1) x0,y0,x1,y1=x1,y1,x0,y0 local dx=(x1-x0)/(y1-y0) @@ -78,11 +76,8 @@ function linefill(ax,ay,bx,by,r,c) for y=y0\1+1,min(y1\1,127) do -- open span? local span=spans[y] - if span then - rectfill(x0,y,span,y) - else - spans[y]=x0 - end + if (span) rectfill(x0,y,span,y) + spans[y]=x0 x0+=dx end x0,y0=_x1,_y1 -- 2.34.1 From 2d565873b3cf1db8403e94173cf5e74ea3fbfbd5 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Thu, 22 Dec 2022 18:32:14 -0800 Subject: [PATCH 10/20] Golf linefill slightly more --- chameleonic.p8 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index 4dbf81a..401cdc4 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -60,12 +60,11 @@ function linefill(ax,ay,bx,by,r,c) local ca,sa=dx/d,-dy/d -- polygon points - local s={{0,-r},{d,-r},{d,r},{0,r}} local spans={} local function calcxy(u,v) return ax+u*ca+v*sa,ay-u*sa+v*ca end local x0,y0=calcxy(0,r) - for i=1,4 do - local x1,y1=calcxy(unpack(s[i])) + for s in all{{0,-r},{d,-r},{d,r},{0,r}} do + local x1,y1=calcxy(unpack(s)) local _x1,_y1=x1,y1 if(y0>y1) x0,y0,x1,y1=x1,y1,x0,y0 local dx=(x1-x0)/(y1-y0) -- 2.34.1 From 94e4aea20b9c4fe29b1ae991ac8b05f39a542db9 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Thu, 22 Dec 2022 18:33:48 -0800 Subject: [PATCH 11/20] Golf _apply --- chameleonic.p8 | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index 401cdc4..edc351d 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -86,11 +86,7 @@ end function _apply(x,ts,a) local t=deli(ts,1) for k,v in pairs(t) do - if k=="update" then - -- - else - x[k]=v - end + if (k!="update") x[k]=v end if (t and t.update and not t.update(x,a)) add(ts,t,1) -- 2.34.1 From ed25ef0f94860ce5d2e9fbfbd3a05c827358066c Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Thu, 22 Dec 2022 18:35:24 -0800 Subject: [PATCH 12/20] Golf sgn0 --- chameleonic.p8 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index edc351d..3d3066c 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -93,8 +93,7 @@ function _apply(x,ts,a) end function sgn0(x) - if (x==0) return x - return sgn(x) + return x!=0 and sgn(x) or 0 end function _mnmx(x,y) -- 2.34.1 From 1be48466984f282611adfdd5f74a3b80b62ac00b Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Thu, 22 Dec 2022 18:42:44 -0800 Subject: [PATCH 13/20] Golf _rast --- chameleonic.p8 | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index 3d3066c..512d466 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -103,13 +103,14 @@ end function _rast( - x0,y0,x1,y1 + xs,ys,x0,y0,x1,y1 ) - local dx=abs(x1-x0) - local dy=abs(y1-y0) - local x=x0 - local y=y0 + local function _add() + local n=#xs + if (n==0 or xs[n]!=x0 or ys[n]!=y0) add(xs,x0) add(ys,y0) + end + local dx,dy=abs(x1-x0),abs(y1-y0) local sx=-1 local sy=-1 if (x0dy then err=dx/2.0 - return function() - if (done) return - if (x==x1) done=true return x1,y1 - local oldx,oldy=x,y + while x0!=x1 do + _add() err-=dy - if (err<0) y+=sy err+=dx - x+=sx - return oldx,oldy + if (err<0) y0+=sy err+=dx + x0+=sx end else err=dy/2.0 - return function() - if (done) return - if (y==y1) done=true return x1,y1 - local oldx,oldy=x,y + while y0!=y1 do + _add() err-=dx - if (err<0) x+=sx err+=dy - y+=sy - return oldx,oldy + if (err<0) x0+=sx err+=dy + y0+=sy end end + _add() end -->8 @@ -1199,12 +1195,7 @@ function rope:_check_sane() local n1=n0.next if (n1==nil) break - for qx,qy in _rast(flr(n0.ax*2),flr(n0.ay*2),flr(n1.ax*2),flr(n1.ay*2)) do - if not (qx==qxs[#qxs] and qy==qys[#qys]) then - add(qxs,qx) - add(qys,qy) - end - end + _rast(qxs,qys,flr(n0.ax*2),flr(n0.ay*2),flr(n1.ax*2),flr(n1.ay*2)) n0=n1 end -- 2.34.1 From 58bf1d70bff18f8f3e3b29ee0c944dabd382a6d1 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Thu, 22 Dec 2022 18:49:03 -0800 Subject: [PATCH 14/20] Golf keyboard --- chameleonic.p8 | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index 512d466..00bb6a9 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -143,47 +143,37 @@ kbd={} add(real_modules,kbd) function kbd:init() self.real=btn() - self.down=0 + self.state={btn=0} end function kbd:update() -- figure out what keys are _really_ pressed - local now_real=btn() - local was_real=self.real + local now_real,was_real=btn(),self.real self.real=now_real -- add keys that are really pressed -- if they weren't really pressed before -- (they may have been force- -- released by :release()) - local real_pressed=(~was_real)&now_real + local real_pressed=~was_real&now_real - local now_down=(self.down&now_real)|real_pressed - local was_down=self.down - self.down=now_down + local state=self.state + local now_down=state.btn&now_real|real_pressed + local was_down=state.btn -- deduce pressed/released by changes in down - local pressed=(~was_down)&now_down - local released=(~now_down)&was_down - - self.pressed=pressed - self.released=released + state.btn,state.btnp,state.btnr= + now_down, + ~was_down&now_down, + ~now_down&was_down end -function kbd:btn(i) - return self.down&(1< Date: Thu, 22 Dec 2022 18:51:05 -0800 Subject: [PATCH 15/20] Golf tostring() --- chameleonic.p8 | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index 00bb6a9..33bbc49 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -177,30 +177,14 @@ function kbd:release(i) end function tostring(any) - if type(any)=="function" then - return "function" - end - if any==nil then - return "nil" - end - if type(any)=="string" then - return any - end - if type(any)=="boolean" then - if any then return "true" end - return "false" - end if type(any)=="table" then - local str = "{ " - for k,v in pairs(any) do - str=str..tostring(k).."->"..tostring(v).." " - end - return str.."}" + local str = "{ " + for k,v in pairs(any) do + str=str..tostring(k).."->"..tostring(v).." " + end + return str.."}" end - if type(any)=="number" then - return ""..any - end - return "unknown" -- should never show + return tostr(any) end -->8 -- 2.34.1 From 9fbccee378dc5925f10eb97c004d60d4205e1886 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Thu, 22 Dec 2022 18:52:54 -0800 Subject: [PATCH 16/20] Golf level selector --- chameleonic.p8 | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index 33bbc49..f6b8c92 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -192,11 +192,7 @@ end title={} add(modules,title) -function title:init() -end - -blinkcol = 10 - +blinkcol=10 function title:draw() cls(0) -- this is right for 72x32 @@ -209,29 +205,18 @@ function title:draw() print(lvlstr,51,90,blinkcol) end -start_level = 0 +start_level=0 max_level=15 function title:update() - if time()*4\1%2==0 then - blinkcol=10 - else - blinkcol=9 - end + blinkcol=9 + if (time()*4\1%2==0) blinkcol=10 - if btnp(0) then - start_level -= 1 - if (start_level<0) start_level=max_level - end - if btnp(1) then - start_level += 1 - if (start_level>max_level) start_level=0 - end - if btnp(4) or btnp(5) then - modules=real_modules - _init() - music(0) - end + if (btnp"0") start_level-=1 + if (btnp"1") start_level+=1 + start_level%=max_level + + if (btnp"4" or btnp"5") modules=real_modules _init() music(0) end -->8 -- 2.34.1 From ae7dc8374e1b078ddfee132812c021ed93e8d91d Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Thu, 22 Dec 2022 19:07:43 -0800 Subject: [PATCH 17/20] Golf level slightly --- chameleonic.p8 | 84 ++++++++++++++++---------------------------------- 1 file changed, 27 insertions(+), 57 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index f6b8c92..863cb6f 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -231,9 +231,7 @@ end function level:reinit(n) self.ix=n self.todo={} - self.bigx=(n%8) - self.bigy=(n\8) - self.next_crate_id=1 + self.bigx,self.bigy=n%8,n\8 self:load_dynobjs() self:recollide() @@ -302,7 +300,7 @@ function level:update() end if #remove>0 then self:recollide() - self:reanchor(true) + self:reanchor() end end @@ -310,6 +308,7 @@ function level:load_dynobjs() self._crates={} self._pits={} + local crate_id=1 for mx=0,15,1 do for my=0,15,1 do local mxy=_mix(mx,my) @@ -319,22 +318,16 @@ function level:load_dynobjs() if def then self._crates[mxy]={ s=s,def=def, - id=self.next_crate_id, + id=crate_id, mx=mx,my=my, px=px,py=py, todo={} } - self.next_crate_id+=1 + crate_id+=1 end - if s==28 then -- pit - self._pits[mxy]={ - s=s, - mx=mx,my=my, - px=px,py=py, - contents=nil - } - end + -- pit + if (s==28) self._pits[mxy]={s=s,mx=mx,my=my,px=px,py=py} end end end @@ -405,17 +398,11 @@ function level:reanchor() end shellsort(self._anch_keys) for point in self:anchor_points() do - if point.ax_old!=nil then - if (player.rope!=nil) player.rope:be_pushed_by(point,point.ax_old,point.ay_old) - point.ax_old=nil - point.ay_old=nil - end - end - for point in self:anchor_points() do - assert(not point.dropped) + if (point.ax_old and player.rope) player.rope:be_pushed_by(point,point.ax_old,point.ay_old) + point.ax_old,point.ay_old=nil,nil end - if (player.rope!=nil) player.rope:relax() + if (player.rope) player.rope:relax() end function level:win_at(mx,my) @@ -485,14 +472,10 @@ end function _amix(ax,ay) return ax..","..ay - --if (ax<0 or ay<0 or ax>31 or ay>31) return nil - --return ay*32+ax end function _mix(mx,my) return mx..","..my - --if (mx<0 or my<0 or mx>15 or my>15) return nil - --return my*16+mx end function level:_get_cratedef(s) @@ -553,35 +536,23 @@ function level:can_move( is_player, mx0,my0,dmx,dmy,exclude_src,exclude_dst ) - if is_player and self:win_at(mx0+dmx,my0+dmy) then - return true - end - if is_player and self:get_open_pit(mx0+dmx,my0+dmy) then - return wrongbleep:adequately_warned() - end + local mx1,my1=mx0+dmx,my0+dmy + if (is_player and self:win_at(mx1,my1)) return true + if (is_player and self:get_open_pit(mx1,my1)) return wrongbleep:adequately_warned() - if self:mcoll(mx0+dmx,my0+dmy) then - return false - end + if (self:mcoll(mx1,my1) or player.x==mx1 and player.y==my1) return false - if player.x==mx0+dmx and player.y==my0+dmy then - return false - end - - -- todo: check tongue collision if player.rope then local chk=false - if dmx==0 and dmy==-1 then - chk=player.rope:collide_mrect(mx0+0.4,my0-0.8,0.2,1.6,exclude_src,exclude_dst) - elseif dmx==0 and dmy==1 then - chk=player.rope:collide_mrect(mx0+0.4,my0+0.2,0.2,1.6,exclude_src,exclude_dst) - elseif dmx==-1 and dmy==0 then - chk=player.rope:collide_mrect(mx0-0.8,my0+0.4,1.6,0.2,exclude_src,exclude_dst) - elseif dmx==1 and dmy==0 then - chk=player.rope:collide_mrect(mx0+0.2,my0+0.4,1.6,0.2,exclude_src,exclude_dst) - end + local w,h=1.6,0.2 + if (dmx==0) w,h=0.2,1.6 - if (chk) return false + if (dmy==-1) rectx,recty=0.4,-0.8 + if (dmy==1) rectx,recty=0.4,0.2 + if (dmx==-1) rectx,recty=-0.8,0.4 + if (dmx==1) rectx,recty=0.2,0.4 + + if (player.rope:collide_mrect(mx0+rectx,my0+recty,w,h,exclude_src,exclude_dst)) return false end return true @@ -590,22 +561,21 @@ end function level:tug_crate(mx0,my0,dmx,dmy) local mxy0=_mix(mx0,my0) local existing=self._crates[mxy0] - if (existing==nil) return + if (not existing) return self._crates[mxy0]=nil - local mx1,my1=mx0+dmx,my0+dmy - local mxy1=_mix(mx1,my1) + local px1,py1=mx1*8,my1*8 existing.todo={ - {px=mx1*8+dmx,py=my1*8+dmy,mx=mx1,my=my1,update=function() + {px=px1+dmx,py=py1+dmy,mx=mx1,my=my1,update=function() self:recollide() self:reanchor() return true end}, - {px=mx1*8,py=my1*8} + {px=px1,py=py1} } - self._crates[mxy1]=existing + self._crates[_mix(mx1,my1)]=existing end -->8 -- 2.34.1 From 930e27a8e365713d04610150bb26a9d65db56d0b Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Thu, 22 Dec 2022 19:22:23 -0800 Subject: [PATCH 18/20] Golf player a bit --- chameleonic.p8 | 112 +++++++++++++++++-------------------------------- 1 file changed, 38 insertions(+), 74 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index 863cb6f..2eb34e0 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -584,54 +584,27 @@ player={} add(real_modules,player) function player:init() - --self:reinit(8,14) - -- don't change this on reinit: -- it stays the same when the level is changed or reloaded self.vanish_frame=0 end function player:reinit(x,y) - self.x=x - self.y=y - self.px=0 - self.py=0 + self.x,self.y=x,y + self.px,self.py=0,0 self.todo={} self.fall_frame=0 - self.reset_frame=0 - self.orientx=-1 - self.orienty=0 - - self.rope=nil -end - -function player:any_busy() - if (#self.todo>0) return true - if (level:busy()) return true - return false + self.orientx,self.orienty=-1,0 end function player:update() - local _addall=function(t,xs) - for i in all(xs) do - add(t,i) - end - end - - local f4 = function(xs) - -- todo: other anim stuff - xs[#xs].px=0 - xs[#xs].py=0 - return xs - end - -- this is a non-gameplay action that takes precedence over -- all gameplay actions self:_vanish_if_requested() - if not self:any_busy() then + if not (#self.todo>0 or level:busy()) then if level:win_at(self.x,self.y) then level:advance() return @@ -660,23 +633,19 @@ function player:update() end -- wait for user to release it else + local function try_move(dx,dy,f) + if (level:can_move(true,self.x,self.y,dx,dy,0,2)) self.todo=f return + wrongbleep:bleep() + end if kbd:btn(0) then - if level:can_move(true,self.x,self.y,-1,0,0,2) then - self.todo=f4({{orientx=-1,orienty=0,px=-2},{px=-7},{x=self.x-1}}) - else wrongbleep:bleep() end + try_move(-1,0,{{orientx=-1,orienty=0,px=-2},{px=-7},{x=self.x-1,px=0}}) elseif kbd:btn(1) then - if level:can_move(true,self.x,self.y,1,0,0,2) then - self.todo=f4({{orientx=1,orienty=0,px=2},{px=7},{x=self.x+1}}) - else wrongbleep:bleep() end + try_move(1,0,{{orientx=1,orienty=0,px=2},{px=7},{x=self.x+1,px=0}}) elseif kbd:btn(2) then - if level:can_move(true,self.x,self.y,0,-1,0,2) then - self.todo=f4({{orienty=-1,py=-2},{py=-7},{y=self.y-1}}) - else wrongbleep:bleep() end + try_move(0,-1,{{orienty=-1,py=-2},{py=-7},{y=self.y-1,py=0}}) elseif kbd:btn(3) then - if level:can_move(true,self.x,self.y,0,1,0,2) then - self.todo=f4({{orienty=1,py=2},{py=7},{y=self.y+1}}) - else wrongbleep:bleep() end - elseif self.rope==nil and kbd:btnr(4) then + try_move(0,1,{{orienty=1,py=2},{py=7},{y=self.y+1,py=0}}) + elseif not self.rope and kbd:btnr(4) then local dx,dy=self.orientx,self.orienty if (dy!=0) dx=0 @@ -695,37 +664,31 @@ function player:update() end }} elseif kbd:btnp(5) then - if self.rope!=nil then - if (not self.rope:tug()) wrongbleep:bleep(9) - end + if (self.rope and not self.rope:tug()) wrongbleep:bleep(9) end end end - if self.rope then - self.rope:update() - end _apply(self,self.todo) if self.rope then self.rope:update() if self.rope:done_reeling() then - self.x=self.rope.latch.rec.mx+self.rope.latch.dx - self.y=self.rope.latch.rec.my+self.rope.latch.dy + local latch=self.rope.latch + self.x=latch.rec.mx+latch.dx + self.y=latch.rec.my+latch.dy end - local rx=self.x+self.px/8+0.5 - local ry=self.y+self.py/8+0.5 - -- do the hokey pokey to work out kinks in the rope - self.rope:drag_dst(rx,ry) + self.rope:drag_dst( + self.x+self.px/8+0.5, + self.y+self.py/8+0.5 + ) local tdx,tdy=self.rope:tug_orientxy() - if (tdx!=0) self.orientx=tdx - if (tdy!=0) self.orienty=tdy + if (tdx) self.orientx=tdx + if (tdy) self.orienty=tdy - if self.rope:done() then - self.rope=nil - end + if (self.rope:done()) self.rope=nil end end @@ -754,23 +717,27 @@ function player:draw() local px=self.x*8+self.px+wrongbleep:vibrate() local py=self.y*8+self.py+wrongbleep:vibrate() - local head=1-self.orienty local vanish_level=max((self.vanish_frame-4)/16,0) local invis_level=max(self.fall_frame/10,4*(vanish_level-0.75)) if (invis_level>=1.0) return - --px+=sin(vanish_level*16)*max(vanish_level-0.1,0)*1 + --[[ local HEAD=14--3 local BODY=12--12 local TAIL=14--14 local IRIS=7--9 local PUPIL=0--0 + ]] - local setpal=function() - -- base colors - pal{ + -- in order: head,body,iris,pupil,body again,tail + local palette=split"-1,14,14,12,12,-1,-1,-1,7,0,-1,12,14,14,14" + local function setpal() + --[[ + -- head + nil,14,14, + --body [2]=HEAD, [3]=HEAD, [4]=BODY, @@ -781,7 +748,8 @@ function player:draw() [13]=TAIL, [14]=TAIL, [15]=TAIL, - } + ]] + pal(palette) -- vanish colors local vanish=split"13,15,14,5,4,12,2,3,9,10" @@ -789,11 +757,7 @@ function player:draw() if (vanish_level>i/#vanish) pal(ilc,1) end - if self.fall_frame>3 then - local zc=@0x5f00&0xf0 - for i=0x5f00,0x5f0c,4 do poke4(i,0x0101.0101) end - poke(0x5f00,zc|0x01) - end + if (self.fall_frame>3) local zc=@0x5f00&0xf0 for i=0x5f00,0x5f0c,4 do poke4(i,0x0101.0101) end poke(0x5f00,zc|0x01) end local rx,ry=self.x*8+self.px+1,self.y*8+self.py+2 @@ -1434,12 +1398,12 @@ function rope:tug_orientxy() local a1=self.dst local a0=self.dst.prev local dx=a0.ax-a1.ax - local tdx=0 + local tdx=nil if (dx>3/8) tdx=1 if (dx<-3/8) tdx=-1 local dy=a0.ay-a1.ay - local tdy=0 + local tdy=nil if abs(dy)>abs(dx)/2 then if (dy>3/8) tdy=1 if (dy<-3/8) tdy=-1 -- 2.34.1 From cf352fd918a53775f158492f68dfecf4734cc2d3 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Thu, 22 Dec 2022 19:23:41 -0800 Subject: [PATCH 19/20] Golf one thing on rope --- chameleonic.p8 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chameleonic.p8 b/chameleonic.p8 index 2eb34e0..0d6b937 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -799,8 +799,8 @@ function rope:new( local r={ id=0, anchors={ - {ax=src_ax,ay=src_ay,prev=nil,next=nil}, - {ax=dst_ax,ay=dst_ay,prev=nil,next=nil} + {ax=src_ax,ay=src_ay}, + {ax=dst_ax,ay=dst_ay} }, state={name="cast",frame=0}, latch=latch, -- 2.34.1 From 10948ce4a5342ee6a4a0e8ea9942e90f7be9c073 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Thu, 22 Dec 2022 19:24:41 -0800 Subject: [PATCH 20/20] Turn off debug again for now --- chameleonic.p8 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chameleonic.p8 b/chameleonic.p8 index 0d6b937..812c428 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -965,6 +965,7 @@ function rope:draw(artificial_px,artificial_py) end -- debug + --[[ local n1=self.src local sy=0 while true do @@ -1011,6 +1012,7 @@ function rope:draw(artificial_px,artificial_py) pset(x+p.adx,y,11) pset(x,y+p.ady,11) end + ]]-- end function rope:drag_dst(x,y) -- 2.34.1