0 D$404mNJNL04e$FHuqaY}},m,Ҫm^ 02TvͫgE#2Tv2Tv; www7www73333wswwwsww3333ww7www7w  oooffffffffallnn."" * *""""""""  ؍(..ߍf``fff`fffff`f``fffffffffffffff`ffff~CSQQQ``QRQQQQQ`QQQQ`P            ?@#-- title: Spread the love -- author: borb -- desc: Spread the love in an uncaring world -- script: lua --shorthand notations for maths functions pi=math.pi max=math.max min=math.min sin=math.sin cos=math.cos exp=math.exp abs=math.abs sqrt=math.sqrt rnd=math.random floor=math.floor ceil=math.ceil str=string.format del=table.remove to=table.insert function rm(tbl,E) for i,v in ipairs(tbl)do if v==E then del(tbl,i)return end end end --buttons (so no need to remember numbers with btn) UP=0 DOWN=1 LEFT=2 RIGHT=3 A=4 --z B=5 --x X=6 --a Y=7 --s SPACE=48 eps=0.0001 t=0 function merge(a,b)--b:n arvot overridaa a:n for k,v in pairs(b) do if (type(v)=="table") and (type(a[k] or false)=="table") then merge(a[k],b[k]) else a[k]=v end end return a end function table.show(a,b,c,d,e,f)local g;local h;if e then for i,j in ipairs(e)do e[i]="[\""..j.."\"]"end end;if f then for i,j in ipairs(f)do f[i]="[\""..j.."\"]"end end;local function k(a)return next(a)==nil end;local function l(m)local n=tostring(m)if type(m)=="function"then return str("%q",n)elseif type(m)=="number"or type(m)=="boolean"then return n else return str("%q",n)end end;local function o(p,c,d,q,r)d=d or""q=q or{}r=r or c;if e and not(d:len()==origindent:len())then if not e[r]then return end end;g=g..d..r;if type(p)~="table"then g=g.." = "..l(p)..";\n"elseif r=="[\"parent\"]"then g=g.." = parent not rendered;\n"elseif f and contains(f,r)then g=g.." = not rendered :);\n"elseif b and p~=a then g=g.." = table not rendered;\n"else if q[p]then g=g.." = {}; -- "..q[p].." (self reference)\n"h=h..c.." = "..q[p]..";\n"else q[p]=c;if k(p)then g=g.." = {};\n"else g=g.." = {\n"for s,j in pairs(p)do s=l(s)local t=str("%s[%s]",c,s)r=str("[%s]",s)o(j,t,d.." ",q,r)end;g=g..d.."};\n"end end end end;if not c and a.name then c=a.name end;c=c or"__unnamed__"if type(a)~="table"then return c.." = "..l(a)end;g,h="",""d=d or""origindent=d;o(a,c,d)return g end function printt(t,name,donts,indent,onlys)trace(table.show(t,false,name,indent,onlys,donts))end --maths helper functions function sign(n) return n>0 and 1 or n<0 and -1 or 0 end function sgn(n) return n>0 and 1 or n<0 and -1 end function clamp(l,n,h) return min(max(n,l),h) end function lerp(a,b,t) return (1-t)*a+t*b end--t=0..1 function len(a,b)return sqrt(a^2+b^2) end function dist(a,b)return len(a.x-b.x,a.y-b.y) end function dir(a,b)return {x=(a.x-b.x)/dist(a,b),y=(a.y-b.y)/dist(a,b)} end function round(num,decplaces) local mult = 10^(decplaces or 0) return math.floor(num*mult+0.5)/mult end function angleAdd(a,d)return (a+d)%(2*pi)end function angleDir(a,b) local d=b-a if abs(d)pi then return -1 elseif d<-pi then return 1 else return d>0 and 1 or -1 end end function anim(f,a)--[[img length,imgs in anim]]return t%(f*a)//f end --show fps, use with print(FPS.fps) FPS={fps=0,frames=0,lastTime=-1000,x=0,y=0,color=14,show=false} function FPS:upd() --original by Al Rado https://tic.computer/play?cart=123 if (time()-self.lastTime <= 1000) then self.frames=self.frames+1 else self.fps=self.frames self.frames=0 self.lastTime=time() end if keyp(SPACE)then FPS.show=not FPS.show end end function FPS:drw() if FPS.show then print(self.fps,self.x,self.y,self.color) end end world={ ents={}, killque={} } function tile(x,y) x=(x)//8 y=(y)//8 local id=mget(x,y) return {x=x*8,y=y*8,id=id} end function collision(ent) --if tile sprite is < 64 and > 0, it's regarded as a collision. ent.x=ent.x+ent.dx if ent.dx<0 then--going left tils={tile(ent.x,ent.y),tile(ent.x,ent.y+7)} for i,til in ipairs(tils) do if til.id>0 and til.id<64 then ent.x=til.x+8 end end else--going right tils={tile(ent.x+8,ent.y),tile(ent.x+8,ent.y+7)} for i,til in ipairs(tils) do if til.id>0 and til.id<64 then ent.x=til.x-8 end end end ent.y=ent.y+ent.dy if ent.dy<0 then--going up tils={tile(ent.x,ent.y),tile(ent.x+7,ent.y)} for i,til in ipairs(tils) do if til.id>0 and til.id<64 then ent.y=til.y+8 end end else--going down tils={tile(ent.x,ent.y+8),tile(ent.x+7,ent.y+8)} for i,til in ipairs(tils) do if til.id>0 and til.id<64 then ent.y=til.y-8 end end end end function death() for i,E in ipairs(world.killque) do if E.death then E:death() end rm(world.ents,E) end world.killque={} end function kill(E)to(world.killque,E)end cam={x=0,y=0,w=240,h=136,scr={x=1,y=1},tx=0,ty=0} --scr x,y: 1...8 --tx,ty: 0,0...239,135 --aiemmin:cx,ccx --scr size:240x136, 30x17 tiles function cam.upd() cam.xold,cam.yold=cam.x,cam.y cam.x,cam.y=Plr.x//cam.w*cam.w,Plr.y//cam.h*cam.h if cam.xold~=cam.x or cam.yold~=cam.y then --change Scr--onScr end cam.scr.x,cam.scr.y=cam.Scr(cam) cam.tx,cam.ty=cam.Tile(cam) end --function cam.Tile(e)return e.x/8+(e.x%8==0 and 1 or 0),e.y/8+(e.y%8==0 and 1 or 0)end function cam.Tile(e)return e.x//8,e.y//8 end function cam.ScrTile(e) return e.x//240*30,e.y//136*17 end function cam.Scr(e)return e.x//240+1,e.y//136+1 end function camIn(x,y)if cam.scr.x==x and cam.scr.y==y then return true end return false end function cam.onScr(e)local x,y=cam.Scr(e)if camIn(x,y) then return true end return false end function EntInsideCircle(Ene,v) if (Ene.x+4-v.x)^2+(Ene.y+4-v.y)^2E.love then if EntInsideCircle(E,v) and E.cooldown==0 then E.love=min(E.love+1,3) sfx(1) E.cooldown=60 end elseif v.love0 then E.cooldown = E.cooldown - 1 end if t%(180/E.love)==0 then newHeart(E) end end to(Enes,E) return E end function Player(E) Plr=merge(E,{hrti=1,hrts={},love=2,name="plr",cooldown=0,spr=64}) function Plr:drw() spr(self.spr+self.love,self.x-cam.x,self.y-cam.y,14) end function Plr:upd() Plr.dx=0 Plr.dy=0 if btn(LEFT) then Plr.dx=-1 end if btn(RIGHT) then Plr.dx=1 end if btn(UP) then Plr.dy=-1 end if btn(DOWN) then Plr.dy=1 end collision(Plr) if btnp(A) then newHeart(Plr) sfx(0) end for i,Ene in ipairs(Enes) do checkIfHrtHitsMe(Ene,Plr) end if Plr.cooldown>0 then Plr.cooldown = Plr.cooldown - 1 end end return Plr end function newHeart(owner) local Hrt={x=owner.x+4,y=owner.y+4,s=1,love=owner.love,owner=owner,cols={6,12},i=t} function Hrt:drw() if Hrt.love==3 then circb(Hrt.x-cam.x,Hrt.y-cam.y,Hrt.s,t//3%8+8) elseif Hrt.love==2 then circb(Hrt.x-cam.x,Hrt.y-cam.y,Hrt.s,12) elseif Hrt.love==1 then circb(Hrt.x-cam.x,Hrt.y-cam.y,Hrt.s,2) end end function Hrt:upd() Hrt.s=Hrt.s+0.8 if Hrt.s>120 then kill(Hrt) end Hrt.tx,Hrt.ty=cam.ScrTile(Hrt) for i=0,29 do for j=0,16 do local tilex=i+Hrt.tx local tiley=j+Hrt.ty local tile=mget(tilex,tiley) if TileInsideCircle(tilex,tiley,Hrt)then if tile==1 then kill(Hrt) elseif tile==96 and Hrt.love>1 then exitt=true end end end end end function Hrt:death() rm(Hrt.owner.hrts,Hrt) end to(owner.hrts,Hrt) to(world.ents,Hrt) return Hrt end to(world.ents,FPS) initEnts() --[[ ]] PALETTE_ADDR=0x03FC0 CHANGE_COL=8 function SCN(r) --local color=(0xff*line/cam.h)//32*32 --poke(PALETTE_ADDR+3*CHANGE_COL, color) poke(0x3ffa,10*sin(0.05*r+0.05*t)) end function OVR() map(cam.tx,cam.ty,30,17,0,0,0,1) for i,v in ipairs(world.ents)do if v.drw then v:drw()end end end function Pir(x,y,w,h,cx,cy) --tri(x,y,w/2+cx,h/2+cy,x+w,y,1) tri(x+w,y,w/2+cx,h/2+cy,x+w,y+h,1) tri(x,y,w/2+cx,h/2+cy,x,y+h,1) -- tri(x+12*sin(t/2400),y+12*cos(t/2400),w/2+12*sin(t/2400),h/2+12*cos(t/2400),x+12*sin(t/2400),y+h+12*sin(t/2400),2) --tri(x,y+h,w/2+cx,h/2+cy,x+w,y+h,15) end function TIC() cls(0) for i,v in ipairs(world.ents)do if v.upd then v:upd()end end cam.upd() for x=0,240,28 do for y=0,136,28 do cx=12*math.sin(t/2400*(x+y+1)) cy=12*math.cos(t/2400*(x+y+1)) Pir(x,y,28,28,x+cx,y+cy) end end death() t=t+1 if exitt then exit() trace("you area winner")end if keyp(18)then reset()end end