diff --git a/game.lua b/game.lua new file mode 100644 index 0000000..072d9ca --- /dev/null +++ b/game.lua @@ -0,0 +1,194 @@ +local game={} +game.__index=game +local sounds=require"sounds" +local gemtypes=require"gemtypes" + +local gem_type_max=#gemtypes + +function game:new(w,h) + local obj=setmetatable({ + w=w,h=h, + gem_tc=3, + board={}, + falling={}, + tofall={}, + fpcache={}, + pfx={}, + dbg={}, + toenerg=0, + batt={display=1,real=1}, + grabs={}, + },self) + for x=1,w do + for y=1,h do + self:spawn_gem(x) + end + end + return obj +end + +function game:pti(x,y) + return y+(x-1)*self.h +end + +function game:get(x,y) + if not self.board[x] then return end + return self.board[x][y] +end + +local function eqgem(a,b) + if not a or not b then return end + return a.t==b.t +end + +local scandirs={ + {-1,0,1},{1,0,1}, + {0,-1,2},{0,1,2} +} + +local function scanrows(hot,get,o) + local rows={} + local seen={} + for _,pos in pairs(hot) do + local row={hot=pos} + local gem = get(o,x,y) + local i=pti(x,y) + if not seen[i] then + seen[i]=true + for _,dir in pairs(scandirs) do + local axis=dirs[3] + row[axis]=row[axis] or {} + local off=0 + local ox,oy=x,y + repeat + off=off+1 + ox=ox+dir[1]*off + oy=oy+dir[2]*off + seen[pti(ox,oy)]=true + until not eqgem(gem,get(o,ox,oy)) + row[axis][dir[axis]*0.5+1.5]=pos[axis]+(off-1)*dir[axis] + end + end + for _,axis in ipairs(row) do + axis[3]=axis[2]-axis[1]+1 + end + rows[row]=true + end + local finrows={} + for row,_ in pairs(rows) do + local mar=0 + for i,axis in ipairs(row) do + mar=math.max(mar,axis[3]) + row[i]=axis[3]>=3 and axis + end + row.mar=mar + if mar<3 then + rows[row]=nil + end + end + return rows +end + +function game:init_fpcache(x) + if self.fpcache[x] then return end + local falls={} + local dead={} + for fall,_ in pairs(self.falling) do + if not fall.die then + falls[#falls+1]=fall + else + dead[fall]=true + end + end + table.sort(falls,function(a,b) + return a.y=y and miy-#fall.gems0 then + local fall={y=0,vel=0,gems={}} + self.falling[x][fall]=true + self.fpcache[x]=nil + self:init_fpcache(x) + end + local i=#topfall.gems+1 + local gtc=math.floor(self.gem_tc) + local infgem=math.random(1,gtc) + local fgem=infgem + repeat + fgem=(fgem)%gtc+1 + topfall.gems[i]=fgem + until fgem==infgem or not next(scanrows({{x,y}},self.get_fall_predict,o)) +end + +function game:kill(posl) + local kc=0 + for _,pos in pairs(posl) do + self.board[pos.x][pos.y]=nil + self.tofall[pos.x]=math.min(self.tofall[pos.x] or self.h,pos.y) + kc=kc+1 + end +end + +function game:check(hot,swaps) + local rows=scanrows(hot,get,self) + local + for row,_ in pairs(rows) do + + end +end + +function game:grab(id,x,y) + grabs[id]={ + pos={x,y}, + ipos={math.floor(x+.5),math.floor(y+.5)}, + off={0,0}, + } +end + +function game:grabmove(id,x,y) + local g=grabs[id] + if not grabs[id] then return end + local dx,dy=x-g.pos[1],y-g.pos[2] + if math.abs(dx)>math.abs(dy) then + dy=0 else dx=0 + end + dx=math.min(1,math.max(-1,math.floor(dx+.5))) + dy=math.min(1,math.max(-1,math.floor(dy+.5))) + off[1],off[2]=dx,dy +end + +function game:ungrab(id,x,y) + +end + +function game:update(dt) + dt=math.min(dt,0.2) +end diff --git a/main.lua b/main.lua index 758196c..6c89882 100644 --- a/main.lua +++ b/main.lua @@ -119,7 +119,7 @@ local function znoise(...) end local soundgen=require"soundgen" local sfx={} -do +--[[do local rate=44100 local len=1 local bfreq=700 @@ -157,6 +157,27 @@ do sd:setSample(n,a) end sfx.boom=love.audio.newSource(sd) +end]] +do + local sg=soundgen + local waves={} + local function sign(n) + return n>0 and 1 or (n<0 and -1 or 0) + end + for n=1,32 do + local a=sg:noise(0):phase(n):freq(50*2^(n^0.8*2)):amp(0.5^(n/2)^1.2) + local b=sg:noise(0):freq(50*n) + waves[n]=sg:new(function(self,t) + local aa=(n)/100 + local t=t + local y=a:sample(t^(0.15*((n-1)^1.1/30+1))+b:sample(t)*aa) + return math.abs(y)^2*sign(y) + end) + end + local wave=sg.add(unpack(waves)):amp(1.2) + wave=wave:fade(0.001,0) + wave=wave:fade(0.001,0.5) + sfx.boom=love.audio.newSource(wave:compile()) end do local sg=soundgen @@ -596,7 +617,7 @@ killall=function(kills,b,...) end if #tt>0 then local boom=sfx.boom:clone() - boom:setVolume(math.min(0.8,0.5+(#tt/10)*0.5)) + boom:setVolume(math.min(0.8,0.3+(#tt/15)*0.7)) boom:setPitch(1.2-math.min(1.2-0.5,#tt/30)) boom:play() sfxs[boom]=true @@ -676,6 +697,7 @@ function love.mousepressed(x,y,b) x,y=x+1-0.5,y+1-0.5 local ix,iy=math.floor(x+.5),math.floor(y+.5) if b==2 and dbg then + taint=1 for ix=ix-50,iy+50 do for iy=iy-50,iy+50 do if board[ix] and board[ix][iy] and math.random()>0.1 then