diff --git a/parts/backgrounds/galaxy.lua b/parts/backgrounds/galaxy.lua index 03dc3ec5..21c3f8a1 100644 --- a/parts/backgrounds/galaxy.lua +++ b/parts/backgrounds/galaxy.lua @@ -1,34 +1,34 @@ --Space with stars local gc=love.graphics local circle,setColor,hsv=gc.circle,gc.setColor,COLOR.hsv -local rnd,pi,sin,cos=math.random,math.pi,math.sin,math.cos +local sin,cos=math.sin,math.cos local back={} local sDist,sRev={},{} -- star data in SoA [distance from center, revolution progress, color] -local k -local d,r -- temp vars for optimization function back.init() if sDist[1]then return end local max for i=0,20 do max=16*(i+1) for j=1,max do - sDist[#sDist+1]=i+rnd() - sRev[#sRev+1]=2*pi*j/max+2*pi*rnd()/max + sDist[#sDist+1]=i+math.random() + sRev[#sRev+1]=MATH.tau*j/max+MATH.tau*math.random()/max end end end -function back.resize(w,h)k=3*SCR.k end function back.update(dt) - for i=1,#sDist do sRev[i]=(sRev[i]+dt/(sDist[i]+1))%(2*pi) end + for i=1,#sDist do + sRev[i]=(sRev[i]+dt/(sDist[i]+1))%MATH.tau + end end function back.draw() gc.clear() gc.translate(SCR.cx,SCR.cy) + gc.scale(SCR.k) gc.rotate(1) for i=1,#sDist do - d,r=sDist[i],sRev[i] + local d,r=sDist[i],sRev[i] if d<5 then setColor(hsv(.088,(d-2)/7,1,.7)) else @@ -36,8 +36,6 @@ function back.draw() end circle('fill',8*d*cos(r),24*d*sin(r),3) end - gc.rotate(-1) - gc.translate(-SCR.cx,-SCR.cy) end -function back.discard()end + return back diff --git a/parts/backgrounds/quarks.lua b/parts/backgrounds/quarks.lua index 4488b4ad..f3b0f89e 100644 --- a/parts/backgrounds/quarks.lua +++ b/parts/backgrounds/quarks.lua @@ -1,32 +1,31 @@ local gc=love.graphics local hsv=COLOR.hsv local circle,push,pop,rot,translate,setColor=gc.circle,gc.push,gc.pop,gc.rotate,gc.translate,gc.setColor -local rnd,sin,cos,twopi,pow,log,ceil=math.random,math.sin,math.cos,2*math.pi,math.pow,math.log,math.ceil +local rnd,sin,cos,log,ceil=math.random,math.sin,math.cos,math.log,math.ceil local back={} local qX,qY,qdX,qdY={},{},{},{} -- quark data in SoA [size, X, Y, dx, dy, color] -local colors={{1,0,0,.8},{0,1,0,.8},{0,0,1,.8}} -local ptcclr={{1,0,0},{0,1,0},{0,0,1}} +local ptcclr={{1,.26,.26},{.26,1,.26},{.26,.26,1}} local apcclr={{0,1,1},{1,0,1},{1,1,0}} local blasts={} -- data about annihilation blasts from particles and antiparticles colliding local ptc={} -- particle-antiparticle data (antiparticle is a mirror of particle) -local nextpair=math.huge +local nextpair local W,H,size local quarkCount=400 -local theta,side,x,y,t,p,cutoff -- temp vars for optimization +local x,y,cutoff -- temp vars for optimization local function spawnQuarkRandom(i) - qX[i]=rnd(W)-10 -- X - qY[i]=rnd(H)-10 -- Y - theta=rnd()*twopi + qX[i]=rnd(W)-10 -- X + qY[i]=rnd(H)-10 -- Y + local theta=rnd()*MATH.tau qdX[i]=cos(theta)*300 -- dx qdY[i]=sin(theta)*300 -- dy end local function spawnQuarkEdge(i) - side=rnd(4) + local side=rnd(4) if side==1 then -- Up edge of screen qX[i]=rnd(SCR.x-10,SCR.ex+10) qY[i]=SCR.y-10 @@ -40,92 +39,91 @@ local function spawnQuarkEdge(i) qX[i]=SCR.x-10 qY[i]=rnd(SCR.y-10,SCR.ey+10) end - theta=rnd()*twopi - qdX[i]=cos(theta)*300 -- dx - qdY[i]=sin(theta)*300 -- dy + local theta=rnd()*MATH.tau + qdX[i]=cos(theta)*300 -- dx + qdY[i]=sin(theta)*300 -- dy end local function spawnParticlePair() x,y=rnd(W)-10,rnd(H)-10 - theta=rnd()*twopi - ptc[#ptc+1]={x=x,y=y,dist=0,theta=theta,v=500, c=rnd(3)} + ptc[#ptc+1]={x=x,y=y,dist=0,theta=rnd()*MATH.tau,v=500, c=rnd(3)} end -local function spawnBlast(_x,_y)blasts[#blasts+1]={x=_x,y=_y,t=0}end +local function spawnBlast(_x,_y) blasts[#blasts+1]={x=_x,y=_y,t=0} end function back.init() qX,qY,qdX,qdY={},{},{},{} blasts={} ptc={} cutoff={ceil(quarkCount/3),ceil(2*quarkCount/3)} + nextpair=0 BG.resize(SCR.w,SCR.h) end function back.resize(w,h) W,H=w+20,h+20 - for i=1,quarkCount do spawnQuarkRandom(i)end + for i=1,quarkCount do spawnQuarkRandom(i) end size=2.6*SCR.k end function back.update(dt) - local debug_dt=TIME() --Move far-away quarks for i=1,quarkCount do qX[i]=qX[i]+qdX[i]*dt qY[i]=qY[i]+qdY[i]*dt - if qX[i]SCR.ex+26 or qY[i]SCR.ey+26 then spawnQuarkEdge(i)end + if qX[i]SCR.ex+26 or qY[i]SCR.ey+26 then + spawnQuarkEdge(i) + end end --Particle pair attraction & destruction - for i=1,#ptc do - p=ptc[i] - if not p then goto continue end - p.dist=p.dist+p.v*dt + for i=#ptc,1,-1 do + local p=ptc[i] + if p then + p.dist=p.dist+p.v*dt + p.v=p.v-p.dist^2*dt - p.v=p.v-pow(p.dist,2)*dt - - --Destroy colliding particle pairs - if p.dist<=10 and p.v<=0 then - spawnBlast(p.x,p.y) - for j=i,#ptc do ptc[j]=ptc[j+1]end - i=i-1 + --Destroy colliding particle pairs + if p.dist<=10 and p.v<=0 then + spawnBlast(p.x,p.y) + table.remove(ptc,i) + end end - ::continue:: end --Age blasts, delete old blasts - for i=1,#blasts do - if not blasts[i]then goto continue end - blasts[i].t=blasts[i].t+dt - - if blasts[i].t>=1 then - for j=i,#blasts do - blasts[j]=blasts[j+1] + for i=#blasts,1,-1 do + if blasts[i] then + blasts[i].t=blasts[i].t+dt + if blasts[i].t>=1 then + table.remove(blasts,i) end - i=i-1 end - ::continue:: end --Spawn particle pairs nextpair=nextpair-dt - if nextpair==math.huge then - nextpair=rnd()+rnd(0,3) - elseif nextpair<=0 then + if nextpair<=0 then spawnParticlePair() - nextpair=rnd()+rnd(0,3) + nextpair=rnd()*4 end end function back.draw() - local debug_dt=TIME() gc.clear(0.08,0.04,0.01) translate(-10,-10) setColor(1,0,0,.8) - for i=1,cutoff[1]do circle('fill',qX[i],qY[i],size)end -- draw red quarks + for i=1,cutoff[1] do -- draw red quarks + circle('fill',qX[i],qY[i],size) + end setColor(0,1,0,.8) - for i=cutoff[1]+1,cutoff[2]do circle('fill',qX[i],qY[i],size)end -- draw green quarks + for i=cutoff[1]+1,cutoff[2] do -- draw green quarks + circle('fill',qX[i],qY[i],size) + end setColor(0,0,1,.8) - for i=cutoff[2]+1,quarkCount do circle('fill',qX[i],qY[i],size) end -- draw blue quarks + for i=cutoff[2]+1,quarkCount do -- draw blue quarks + circle('fill',qX[i],qY[i],size) + end for i=1,#ptc do - p=ptc[i] + local p=ptc[i] push() - translate(p.x,p.y)rot(p.theta) + translate(p.x,p.y) + rot(p.theta) setColor(ptcclr[p.c]) circle('fill', p.dist,0,4*size) @@ -134,17 +132,16 @@ function back.draw() pop() end for i=1,#blasts do - t=blasts[i].t + local t=blasts[i].t setColor(hsv(-80*t,1-1.7*log(5*t,10),1,1-t)) - circle('fill',blasts[i].x,blasts[i].y,40*log(3*t+1.7,3)) + circle('fill',blasts[i].x,blasts[i].y,62*t^.5) end - translate(10,10) end function back.discard() qX,qY,qdX,qdY,qC=nil,nil,nil,nil,nil blasts=nil ptc=nil nextpair=math.huge - collectgarbage('collect') + collectgarbage() end return back