Compare commits

...

1 Commits

Author SHA1 Message Date
MrZ_26
a85da670c8 Alpha V0.1+ 2020-02-04 19:26:04 +08:00
11 changed files with 342 additions and 171 deletions

Binary file not shown.

90
ai.lua
View File

@@ -8,7 +8,7 @@ FilledLines
TetrisShape TetrisShape
BlockedWells; BlockedWells;
]] ]]
spinNeed={2,2,4,4,4,1,2} dirCount={1,1,3,3,3,0,1}
spinOffset={ spinOffset={
{1,0,0},--S {1,0,0},--S
{1,0,0},--Z {1,0,0},--Z
@@ -19,44 +19,27 @@ spinOffset={
{2,0,1},--I {2,0,1},--I
}for i=1,7 do spinOffset[i][0]=0 end }for i=1,7 do spinOffset[i][0]=0 end
function ifoverlapAI(f,bk,x,y)
local count=0 if y<1 then return true end
RowFree={}for i=1,16 do RowFree[i]={}end if y>#f then return nil end
function getNewRow(len)
count=count+1
if count==17 then count=1 end
for i=1,len do
RowFree[count][i]=0
end
return RowFree[count]
end
--Cache manage
function ifoverlapAI(field,bk,x,y)
if x<1 or x+#bk[1]>11 or y<1 then return true end
if y>#field then return nil end
for i=1,#bk do for j=1,#bk[1]do for i=1,#bk do for j=1,#bk[1]do
if field[y+i-1]and bk[i][j]>0 and field[y+i-1][x+j-1]>0 then return true end if f[y+i-1]and bk[i][j]>0 and f[y+i-1][x+j-1]>0 then return true end
end end end end
end end
function resetField(f0,start,ifOrigion) function resetField(f0,f,start)
while field[start]do while f[start]do
rem(field,start) removeRow(f,start)
end end
for i=start,#f0 do for i=start,#f0 do
if ifOrigion then f[i]=getNewRow()
field[i]=f0[i] for j=1,10 do
else f[i][j]=f0[i][j]
field[i]={}
for j=1,10 do
field[i][j]=f0[i][j]
end
end end
end end
end end
function getScore(field,cb,cx,cy) function getScore(field,cb,cx,cy)
local highest=0 local highest=0
local height=getNewRow(0) local height=getNewRow()
local rough=0 local rough=0
local clear=0 local clear=0
local hole=0 local hole=0
@@ -67,7 +50,7 @@ function getScore(field,cb,cx,cy)
if field[i][j]==0 then f=false;break end if field[i][j]==0 then f=false;break end
end end
if f then if f then
rem(field,i) removeRow(field,i)
clear=clear+1 clear=clear+1
end end
end end
@@ -81,62 +64,67 @@ function getScore(field,cb,cx,cy)
if x>3 and x<8 and h>highest then highest=h end if x>3 and x<8 and h>highest then highest=h end
if h>1 then if h>1 then
for h=h-1,1,-1 do for h=h-1,1,-1 do
if field[h][x]==0 then hole=hole+1 end if field[h][x]==0 then hole=hole+1 if hole>5 then break end end
end end
end end
end end
for x=1,9 do for x=1,9 do
local dh=abs(height[x]-height[x]) local dh=abs(height[x]-height[x])
if dh>1 then if dh>1 then
rough=rough+dh^1.5 rough=rough+min(dh^2,10)
end end
end end
ins(freeRow,height)
return return
-highest*5 -highest*5
-rough*20 -rough*15
-cy*15 -cy*20
-#cb*10
+clear^2*4 +clear^2*4
-hole*20 -hole*15
end end
--controlname:mL,mR,rR,rL,rF,hD,sD,H,LL,RR --controlname:mL,mR,rR,rL,rF,hD,sD,H,LL,RR
function AI_getControls(ctrl) function AI_getControls(ctrl)
local field_org,cb,cx,cy={} local Tfield={}--test field
for i=1,#field do local field_org=field
field_org[i]={} for i=1,#field_org do
Tfield[i]=getNewRow()
for j=1,10 do for j=1,10 do
field_org[i][j]=field[i][j] Tfield[i][j]=field_org[i][j]
end end
end end
local best={x=1,dir=0,hold=false,score=-9e99} local best={x=1,dir=0,hold=false,score=-9e99}
for ifhold=0,1 do for ifhold=0,1 do
local bn=ifhold==0 and bn or hn>0 and hn or nxt[1] local bn=ifhold==0 and bn or hn>0 and hn or nxt[1]
for dir=0,spinNeed[bn]-1 do--for each direction for dir=0,dirCount[bn] do--for each direction
cb=blocks[bn][dir] local cb=blocks[bn][dir]
for cx=1,11-#cb[1]do--for each positioon for cx=1,11-#cb[1]do--for each positioon
cy=#field+1 local cy=#Tfield+1
while not ifoverlapAI(field,cb,cx,cy-1)do while not ifoverlapAI(Tfield,cb,cx,cy-1)do
cy=cy-1 cy=cy-1
end--move to bottom end--move to bottom
for i=1,#cb do for i=1,#cb do
local y=cy+i-1 local y=cy+i-1
if not field[y]then field[y]=getNewRow(10)end if not Tfield[y]then Tfield[y]=getNewRow()end
for j=1,#cb[1]do for j=1,#cb[1]do
if cb[i][j]~=0 then if cb[i][j]~=0 then
field[y][cx+j-1]=1 Tfield[y][cx+j-1]=1
end end
end end
end--simulate lock end--simulate lock
local score=getScore(field,cb,cx,cy) local score=getScore(Tfield,cb,cx,cy)
if score>best.score then if score>best.score then
best={bn=bn,x=cx,dir=dir,hold=ifhold==1,score=score} best={bn=bn,x=cx,dir=dir,hold=ifhold==1,score=score}
end end
resetField(field_org,cy) resetField(field_org,Tfield,cy)
end end
end end
end--ifHold end--ifHold loop
resetField(field_org,cy,true)--True reset,no temp pointer
while #Tfield>0 do
removeRow(Tfield,1)
end--Release cache
cb,cx,cy=cb_org,cx_org,cy_org
if best.hold then if best.hold then
ins(ctrl,8) ins(ctrl,8)
end end
@@ -146,7 +134,7 @@ function AI_getControls(ctrl)
ins(ctrl,5) ins(ctrl,5)
elseif best.dir==3 then elseif best.dir==3 then
ins(ctrl,4) ins(ctrl,4)
end--rotate end--hold&rotate
best.x=best.x-spinOffset[best.bn][best.dir] best.x=best.x-spinOffset[best.bn][best.dir]
local n=blockPos[best.bn]<best.x and 2 or 1 local n=blockPos[best.bn]<best.x and 2 or 1
for i=1,abs(blockPos[best.bn]-best.x)do for i=1,abs(blockPos[best.bn]-best.x)do

View File

@@ -13,7 +13,7 @@ Buttons={
{x=640,y=140,w=280,h=70,rgb=color.white,t="Zen",code=function()startGame("zen")end,down=5,left=1,right=3}, {x=640,y=140,w=280,h=70,rgb=color.white,t="Zen",code=function()startGame("zen")end,down=5,left=1,right=3},
{x=950,y=140,w=280,h=70,rgb=color.white,t="GM Roll",code=function()startGame("gmroll")end,down=6,left=2}, {x=950,y=140,w=280,h=70,rgb=color.white,t="GM Roll",code=function()startGame("gmroll")end,down=6,left=2},
{x=330,y=250,w=280,h=70,rgb=color.white,t="Marathon",code=function()startGame("marathon")end,up=1,down=7,right=5}, {x=330,y=250,w=280,h=70,rgb=color.white,t="Marathon",code=function()startGame("marathon")end,up=1,down=7,right=5},
{x=640,y=250,w=280,h=70,rgb=color.white,t="Tetris 25",code=function()startGame("tetris25")end,up=2,down=8,left=4,right=6}, {x=640,y=250,w=280,h=70,rgb=color.white,t="Tetris 21",code=function()startGame("tetris21")end,up=2,down=8,left=4,right=6},
{x=950,y=250,w=280,h=70,rgb=color.white,t="Blind",code=function()startGame("blind")end,up=3,down=9,left=5}, {x=950,y=250,w=280,h=70,rgb=color.white,t="Blind",code=function()startGame("blind")end,up=3,down=9,left=5},
{x=330,y=360,w=280,h=70,rgb=color.white,t="Death",code=function()startGame("death")end,up=4,down=10,right=8}, {x=330,y=360,w=280,h=70,rgb=color.white,t="Death",code=function()startGame("death")end,up=4,down=10,right=8},
{x=640,y=360,w=280,h=70,rgb=color.white,t="AI Solo",code=function()startGame("solo")end,up=5,down=10,right=9,left=7}, {x=640,y=360,w=280,h=70,rgb=color.white,t="AI Solo",code=function()startGame("solo")end,up=5,down=10,right=9,left=7},
@@ -38,21 +38,39 @@ Buttons={
{x=640,y=590,w=180,h=60,rgb=color.white,t="Back",code=function()back()end,up=6}, {x=640,y=590,w=180,h=60,rgb=color.white,t="Back",code=function()back()end,up=6},
}, },
setting2={ setting2={
{x=420,y=70,w=190,h=45,rgb=color.white,t=function()return setting.key[1]end,code=function()keysetting=1 end,down=2,right=10}, {x=290,y=70 ,w=160,h=45,rgb=color.white,t=function()return setting.key[1]end,code=function()keysetting,gamepadsetting=1 end,up=1,down=2,right=10},
{x=420,y=130,w=190,h=45,rgb=color.white,t=function()return setting.key[2]end,code=function()keysetting=2 end,up=1,down=3,right=10}, {x=290,y=130,w=160,h=45,rgb=color.white,t=function()return setting.key[2]end,code=function()keysetting,gamepadsetting=2 end,up=1,down=3,right=11},
{x=420,y=190,w=190,h=45,rgb=color.white,t=function()return setting.key[3]end,code=function()keysetting=3 end,up=2,down=4,right=10}, {x=290,y=190,w=160,h=45,rgb=color.white,t=function()return setting.key[3]end,code=function()keysetting,gamepadsetting=3 end,up=2,down=4,right=12},
{x=420,y=250,w=190,h=45,rgb=color.white,t=function()return setting.key[4]end,code=function()keysetting=4 end,up=3,down=5,right=10}, {x=290,y=250,w=160,h=45,rgb=color.white,t=function()return setting.key[4]end,code=function()keysetting,gamepadsetting=4 end,up=3,down=5,right=13},
{x=420,y=310,w=190,h=45,rgb=color.white,t=function()return setting.key[5]end,code=function()keysetting=5 end,up=4,down=6,right=10}, {x=290,y=310,w=160,h=45,rgb=color.white,t=function()return setting.key[5]end,code=function()keysetting,gamepadsetting=5 end,up=4,down=6,right=14},
{x=420,y=370,w=190,h=45,rgb=color.white,t=function()return setting.key[6]end,code=function()keysetting=6 end,up=5,down=7,right=10}, {x=290,y=370,w=160,h=45,rgb=color.white,t=function()return setting.key[6]end,code=function()keysetting,gamepadsetting=6 end,up=5,down=7,right=15},
{x=420,y=430,w=190,h=45,rgb=color.white,t=function()return setting.key[7]end,code=function()keysetting=7 end,up=6,down=8,right=10}, {x=290,y=430,w=160,h=45,rgb=color.white,t=function()return setting.key[7]end,code=function()keysetting,gamepadsetting=7 end,up=6,down=8,right=16},
{x=420,y=490,w=190,h=45,rgb=color.white,t=function()return setting.key[8]end,code=function()keysetting=8 end,up=7,down=9,right=10}, {x=290,y=490,w=160,h=45,rgb=color.white,t=function()return setting.key[8]end,code=function()keysetting,gamepadsetting=8 end,up=7,down=9,right=17},
{x=420,y=550,w=190,h=45,rgb=color.white,t=function()return setting.key[9]end,code=function()keysetting=9 end,up=8,down=14,right=15}, {x=290,y=550,w=160,h=45,rgb=color.white,t=function()return setting.key[9]end,code=function()keysetting,gamepadsetting=9 end,up=8,down=27,right=18},
{x=745,y=90,w=40,h=40,rgb=color.white,t="-",code=function()setting.das=(setting.das-1)%31 end,hold=true,left=1,right=11,down=15}, --1~9
{x=910,y=90,w=40,h=40,rgb=color.white,t="+",code=function()setting.das=(setting.das+1)%31 end,hold=true,left=10,right=12,down=15}, {x=540,y=70 ,w=230,h=45,rgb=color.white,t=function()return setting.gamepad[1]end,code=function()gamepadsetting,keysetting=1 end,up=10,down=11,left=1,right=19},
{x=960,y=90,w=40,h=40,rgb=color.white,t="-",code=function()setting.arr=(setting.arr-1)%16 end,hold=true,left=11,right=13,down=15}, {x=540,y=130,w=230,h=45,rgb=color.white,t=function()return setting.gamepad[2]end,code=function()gamepadsetting,keysetting=2 end,up=10,down=12,left=2,right=19},
{x=1125,y=90,w=40,h=40,rgb=color.white,t="+",code=function()setting.arr=(setting.arr+1)%16 end,hold=true,left=12,down=15}, {x=540,y=190,w=230,h=45,rgb=color.white,t=function()return setting.gamepad[3]end,code=function()gamepadsetting,keysetting=3 end,up=11,down=13,left=3,right=23},
{x=420,y=630,w=120,h=55,rgb=color.white,t="Reset",code=function()for i=1,#setting.key do setting.key[i]=gameEnv0.key[i] end end,up=9,right=15}, {x=540,y=250,w=230,h=45,rgb=color.white,t=function()return setting.gamepad[4]end,code=function()gamepadsetting,keysetting=4 end,up=12,down=14,left=4,right=23},
{x=640,y=590,w=180,h=60,rgb=color.white,t="Back",code=function()keysetting=nil;back()end,left=9,up=9}, {x=540,y=310,w=230,h=45,rgb=color.white,t=function()return setting.gamepad[5]end,code=function()gamepadsetting,keysetting=5 end,up=13,down=15,left=5,right=28},
{x=540,y=370,w=230,h=45,rgb=color.white,t=function()return setting.gamepad[6]end,code=function()gamepadsetting,keysetting=6 end,up=14,down=16,left=6,right=28},
{x=540,y=430,w=230,h=45,rgb=color.white,t=function()return setting.gamepad[7]end,code=function()gamepadsetting,keysetting=7 end,up=15,down=17,left=7,right=28},
{x=540,y=490,w=230,h=45,rgb=color.white,t=function()return setting.gamepad[8]end,code=function()gamepadsetting,keysetting=8 end,up=16,down=18,left=8,right=28},
{x=540,y=550,w=230,h=45,rgb=color.white,t=function()return setting.gamepad[9]end,code=function()gamepadsetting,keysetting=9 end,up=17,down=27,left=9,right=28},
--10~18
{x=745,y=90,w=40,h=40,rgb=color.white,t="-",code=function()setting.das=(setting.das-1)%31 end,hold=true,left=10,right=20,down=23},
{x=910,y=90,w=40,h=40,rgb=color.white,t="+",code=function()setting.das=(setting.das+1)%31 end,hold=true,left=19,right=21,down=24},
{x=960,y=90,w=40,h=40,rgb=color.white,t="-",code=function()setting.arr=(setting.arr-1)%16 end,hold=true,left=20,right=22,down=25},
{x=1125,y=90,w=40,h=40,rgb=color.white,t="+",code=function()setting.arr=(setting.arr+1)%16 end,hold=true,left=21,down=26},
--19~22
{x=745,y=150,w=40,h=40,rgb=color.white,t="-",code=function()setting.sddas=(setting.sddas-1)%11 end,hold=true,up=19,down=28,left=10,right=24},
{x=910,y=150,w=40,h=40,rgb=color.white,t="+",code=function()setting.sddas=(setting.sddas+1)%11 end,hold=true,up=20,down=28,left=23,right=25},
{x=960,y=150,w=40,h=40,rgb=color.white,t="-",code=function()setting.sdarr=(setting.sdarr-1)%6 end,hold=true,up=21,down=28,left=24,right=26},
{x=1125,y=150,w=40,h=40,rgb=color.white,t="+",code=function()setting.sdarr=(setting.sdarr+1)%4 end,hold=true,up=22,down=28,left=25},
--23~26
{x=405,y=630,w=130,h=60,rgb=color.white,t="Reset",code=function()for i=1,#setting.key do setting.key[i]=gameEnv0.key[i] end end,up=9,right=28},
{x=840,y=630,w=180,h=60,rgb=color.white,t="Back",code=function()keysetting=nil;back()end,up=9,left=27},
--27~28
}, },
help={ help={
{x=640,y=590,w=180,h=60,rgb=color.white,t="Back",code=function()back()end}, {x=640,y=590,w=180,h=60,rgb=color.white,t="Back",code=function()back()end},

View File

@@ -7,7 +7,7 @@ function love.conf(t)
t.accelerometerjoystick=X--Enable the accelerometer on iOS and Android by exposing it as a Joystick (boolean) t.accelerometerjoystick=X--Enable the accelerometer on iOS and Android by exposing it as a Joystick (boolean)
t.externalstorage=X t.externalstorage=X
t.gammacorrect=true t.gammacorrect=true
-- t.audio.mixwithsystem=true--Keep background music playing when opening LOVE (boolean, iOS and Android only) -- t.audio.mixwithsystem=true--Keep background music playing when opening LOVE (boolean, iOS and Android only)
t.window.title="Techmino Alpha" t.window.title="Techmino Alpha"
t.window.icon="/image/icon.png" t.window.icon="/image/icon.png"
@@ -23,27 +23,27 @@ function love.conf(t)
t.window.msaa=X--The number of samples to use with multi-sampled antialiasing (number) t.window.msaa=X--The number of samples to use with multi-sampled antialiasing (number)
t.window.depth=X--The number of bits per sample in the depth buffer t.window.depth=X--The number of bits per sample in the depth buffer
t.window.stencil=1--The number of bits per sample in the stencil buffer t.window.stencil=1--The number of bits per sample in the stencil buffer
t.window.display=1--Index of the monitor to show the window in (number) t.window.display=1--Monitor ID
t.window.highdpi=X--Enable high-dpi mode for the window on a Retina display (boolean) t.window.highdpi=X--Enable high-dpi mode for the window on a Retina display (boolean)
t.window.x=nil t.window.x=nil
t.window.y=nil t.window.y=nil
t.modules.window=true
t.modules.system=true
t.modules.audio=true t.modules.audio=true
t.modules.data=true t.modules.data=true
t.modules.event=true t.modules.event=true
t.modules.font=true t.modules.font=true
t.modules.graphics=true t.modules.graphics=true
t.modules.image=true t.modules.image=true
t.modules.joystick=X t.modules.joystick=true
t.modules.keyboard=true t.modules.keyboard=true
t.modules.math=true t.modules.math=true
t.modules.mouse=true t.modules.mouse=true
t.modules.physics=X
t.modules.sound=true t.modules.sound=true
t.modules.system=true
t.modules.thread=X
t.modules.timer=true t.modules.timer=true
t.modules.touch=X t.modules.touch=true
t.modules.physics=X
t.modules.thread=X
t.modules.video=X t.modules.video=X
t.modules.window=true
end end

View File

@@ -1,4 +1,42 @@
function buttonControl_key(i)
mouseShow=false
if i=="up"or i=="down"or i=="left"or i=="right"then
if not Buttons.sel then
Buttons.sel=1
else
Buttons.sel=Buttons[scene][Buttons.sel][i]or Buttons.sel
end
elseif i=="space"or i=="return"then
if not sceneSwaping and Buttons.sel then
local B=Buttons[scene][Buttons.sel]
B.code()
B.alpha=1
sysSFX("button")
end
end
end
function buttonControl_gamepad(i)
if i=="dpup"or i=="dpdown"or i=="dpleft"or i=="dpright"then
if not Buttons.sel then
Buttons.sel=1
mouseShow=false
else
Buttons.sel=Buttons[scene][Buttons.sel][i=="dpup"and"up"or i=="dpdown"and"down"or i=="dpleft"and"left"or"right"]or Buttons.sel
end
elseif i=="start"then
if not sceneSwaping and Buttons.sel then
local B=Buttons[scene][Buttons.sel]
if B.hold then Buttons.pressing=max(Buttons.pressing,1)end
B.code()
B.alpha=1
sysSFX("button")
end
end
end
function love.mousemoved(x,y) function love.mousemoved(x,y)
mouseShow=true
mx,my=mouseConvert(x,y) mx,my=mouseConvert(x,y)
Buttons.sel=nil Buttons.sel=nil
for i=1,#Buttons[scene]do for i=1,#Buttons[scene]do
@@ -13,6 +51,7 @@ function love.mousemoved(x,y)
if not Buttons.sel then Buttons.pressing=0 end if not Buttons.sel then Buttons.pressing=0 end
end end
function love.mousepressed(x,y,k) function love.mousepressed(x,y,k)
mouseShow=true
mx,my=mouseConvert(x,y) mx,my=mouseConvert(x,y)
if mouseDown[scene]then mouseDown[scene](mx,my,k)end if mouseDown[scene]then mouseDown[scene](mx,my,k)end
if k==1 then if k==1 then
@@ -23,7 +62,7 @@ function love.mousepressed(x,y,k)
B.alpha=1 B.alpha=1
Buttons.sel=nil Buttons.sel=nil
love.mousemoved(x,y) love.mousemoved(x,y)
SFX("button") sysSFX("button")
end end
elseif k==3 then elseif k==3 then
back() back()
@@ -45,31 +84,44 @@ function love.touchmoved(id,x,y,dx,dy)
end end
function love.keypressed(i) function love.keypressed(i)
if scene~="play"or scene=="setting2"and not keysetting then if keyDown[scene]then keyDown[scene](i)
if i=="up"or i=="down"or i=="left"or i=="right"then elseif i=="escape"then back()
if not Buttons.sel then else buttonControl_key(i)
Buttons.sel=1
else
Buttons.sel=Buttons[scene][Buttons.sel][i]or Buttons.sel
end
elseif i=="space"or i=="return"then
if not sceneSwaping and Buttons.sel then
local B=Buttons[scene][Buttons.sel]
if B.hold then Buttons.pressing=max(Buttons.pressing,1)end
B.code()
B.alpha=1
SFX("button")
end
end
end
if keyDown[scene]then return keyDown[scene](i)
elseif i=="escape"then return back()
end end
end end
function love.keyreleased(i) function love.keyreleased(i)
if keyUp[scene]then keyUp[scene](i) if keyUp[scene]then keyUp[scene](i)
end end
end end
function love.gamepadpressed(joystick,i)
if scene~="play"or scene=="setting2"and not gamepadsetting then
if i=="dpup"or i=="dpdown"or i=="dpleft"or i=="dpright"then
if not Buttons.sel then
Buttons.sel=1
mouseShow=false
else
Buttons.sel=Buttons[scene][Buttons.sel][i]or Buttons.sel
end
elseif i=="start"then
if not sceneSwaping and Buttons.sel then
local B=Buttons[scene][Buttons.sel]
if B.hold then Buttons.pressing=max(Buttons.pressing,1)end
B.code()
B.alpha=1
sysSFX("button")
end
end
end
if gamepadDown[scene]then return gamepadDown[scene](i)
elseif i=="back"then return back()
end
end
function love.gamepadreleased(joystick,i)
if gamepadUp[scene]then gamepadUp[scene](i)
end
end
function love.wheelmoved(x,y) function love.wheelmoved(x,y)
if wheelmoved[scene]then wheelmoved[scene](x,y)end if wheelmoved[scene]then wheelmoved[scene](x,y)end
end end

View File

@@ -28,7 +28,7 @@ function game.play()
scene="play" scene="play"
--curBG="game1" --curBG="game1"
resetGameData() resetGameData()
SFX("ready") sysSFX("ready")
end end
function game.setting() function game.setting()
scene="setting" scene="setting"

13
lists.lua Normal file
View File

@@ -0,0 +1,13 @@
loseReason={"Finished","Block out"}
blockName={"Z","S","L","J","T","O","I"}
clearName={"Single","Double","Triple"}
actName={"moveLeft","moveRight","rotRight","rotLeft","rotFlip","hardDrop","softDrop","hold","restart","toLeft","toRight"}
actName_show={"move left","move right","rotate right","rotate left","rotate flip","hard drop","soft drop","hold","restart","toLeft","toRight"}
blockPos={4,4,4,4,4,5,4}
renATK={[0]=0,0,0,1,1,2,2,3,3,3}--4 else
b2bATK={3,5,8}
marathon_drop={[0]=60,48,40,30,24,18,15,12,10,8,7,6,5,4,3,2,1,1,0,0}
death_lock={10,9,8,7,6}
death_wait={6,5,4,3,2}
death_fall={10,8,7,6,5}

196
main.lua
View File

@@ -3,6 +3,40 @@ toN,toS=tonumber,tostring
int,ceil,abs,rnd,max,min,sin,cos,atan,pi=math.floor,math.ceil,math.abs,math.random,math.max,math.min,math.sin,math.cos,math.atan,math.pi int,ceil,abs,rnd,max,min,sin,cos,atan,pi=math.floor,math.ceil,math.abs,math.random,math.max,math.min,math.sin,math.cos,math.atan,math.pi
sub,gsub,find,format,byte,char=string.sub,string.gsub,string.find,string.format,string.byte,string.char sub,gsub,find,format,byte,char=string.sub,string.gsub,string.find,string.format,string.byte,string.char
ins,rem,sort=table.insert,table.remove,table.sort ins,rem,sort=table.insert,table.remove,table.sort
--[[
freeRow={}
for i=1,50 do
freeRow[i]={0,0,0,0,0,0,0,0,0,0}
end
]]--Reset freeRow,in resetGameData
function getNewRow(val)
if not val then val=0 end
local t=rem(freeRow)
for i=1,10 do
t[i]=val or 0
end
--clear a row and move to active list
if #freeRow==0 then
for i=1,20 do
ins(freeRow,{0,0,0,0,0,0,0,0,0,0})
end
end
--prepare new rows
return t
end
function removeRow(t,k)
ins(freeRow,rem(t,k))
end
function restockRow()
for p=1,#players do
local f,f2=players[p].field,players[p].visTime
while #f>0 do
removeRow(f,1)
removeRow(f2,1)
end
end
end
--to save cache,all rows pruduced and removed here!
function sortByTime(a,b) function sortByTime(a,b)
return a.time>b.time return a.time>b.time
@@ -10,7 +44,7 @@ end
ww,wh=gc.getWidth(),gc.getHeight() ww,wh=gc.getWidth(),gc.getHeight()
Timer=tm.getTime Timer=tm.getTime--Easy get time
mx,my,mouseShow=-10,-10,true mx,my,mouseShow=-10,-10,true
pause=0--pause countdown(frame) pause=0--pause countdown(frame)
focus=true focus=true
@@ -26,7 +60,10 @@ languages={"eng"}
prevMenu={ prevMenu={
load=love.event.quit, load=love.event.quit,
ready="mode", ready="mode",
play="mode", play=function()
restockRow()
gotoScene("mode")
end,
mode="main", mode="main",
help="main", help="main",
stat="main", stat="main",
@@ -199,38 +236,30 @@ color={
} }
attackColor={ attackColor={
{color.red,color.yellow}, {color.red,color.yellow},
{color.red,color.cyan}, {color.red,color.purple},
{color.blue,color.white}, {color.blue,color.white},
animate={ animate={
function(t) function(t)
gc.setColor(1,t,0) gc.setColor(1,t,0)
end, end,
function(t) function(t)
gc.setColor(1-t,t,t) gc.setColor(1,0,t)
end, end,
function(t) function(t)
gc.setColor(t,t,1) gc.setColor(t,t,1)
end, end,
} }--3 animation-colorsets of attack buffer bar
} }
-- for k,v in pairs(color) do -- for k,v in pairs(color) do
-- v[1],v[2],v[3]=255*v[1],255*v[2],255*v[3] -- v[1],v[2],v[3]=255*v[1],255*v[2],255*v[3]
-- end -- end
loseReason={"Finished","Block out"}
blockName={"Z","S","L","J","T","O","I"}
clearName={"Single","Double","Triple"}
actName={"moveLeft","moveRight","rotRight","rotLeft","rotFlip","hardDrop","softDrop","hold","restart","toLeft","toRight"}
actName_show={"move left","move right","rotate right","rotate left","rotate flip","hard drop","soft drop","hold","restart","toLeft","toRight"}
blockPos={4,4,4,4,4,5,4}
renATK={[0]=0,0,0,1,1,2,2,3,3,3}--4 else
b2bATK={3,5,8}
require("TRS")--load block&TRS kick require("TRS")--load block&TRS kick
require("lists")
marathon_drop={[0]=60,48,40,30,24,18,15,12,10,8,7,6,5,4,3,2,1,1,0,0}
gameEnv0={ gameEnv0={
das=6,arr=1, das=10,arr=2,
sddas=0,sdarr=2,
ghost=true,center=true, ghost=true,center=true,
drop=30,lock=45, drop=30,lock=45,
wait=0,fall=20, wait=0,fall=20,
@@ -239,6 +268,7 @@ gameEnv0={
_20G=false,target=9e99, _20G=false,target=9e99,
freshLimit=9e99, freshLimit=9e99,
key={"left","right","x","z","c","up","down","space","LEFT","RIGHT"}, key={"left","right","x","z","c","up","down","space","LEFT","RIGHT"},
gamepad={"dpleft","dpright","a","b","y","dpup","dpdown","rightshoulder","leftshoulder","LEFT","RIGHT"},
reach=function()end,--Called when reach row target reach=function()end,--Called when reach row target
} }
randomMethod={ randomMethod={
@@ -341,7 +371,7 @@ loadmode={
curBG="game2" curBG="game2"
BGM("push") BGM("push")
end, end,
tetris25=function() tetris21=function()
modeEnv={ modeEnv={
wait=1, wait=1,
fall=1, fall=1,
@@ -444,30 +474,17 @@ Event={
end end
end, end,
death_reach=function() death_reach=function()
if gameEnv.target==50 then if gameEnv.target==250 then
gameEnv.lock=9 Event.gameover.win()
gameEnv.wait=5 else
gameEnv.fall=8 gameEnv.target=gameEnv.target+50
showText("STAGE 2","fly",80,-100) local t=gameEnv.target/50
elseif gameEnv.target==100 then gameEnv.lock=death_lock[t]
gameEnv.lock=8 gameEnv.wait=death_wait[t]
gameEnv.wait=4 gameEnv.fall=death_fall[t]
gameEnv.fall=6 showText("STAGE "..t,"fly",80,-120)
showText("STAGE 3","fly",80,-100) SFX("reach")
elseif gameEnv.target==150 then
gameEnv.lock=7
gameEnv.wait=3
gameEnv.fall=5
showText("STAGE 4","fly",80,-100)
elseif gameEnv.target==200 then
gameEnv.lock=6
gameEnv.wait=2
gameEnv.fall=4
showText("STAGE 5","fly",80,-100)
gameEnv.target=250
end end
gameEnv.target=gameEnv.target+50
SFX("reach")
end, end,
task={ task={
win=function() win=function()
@@ -522,7 +539,7 @@ mesDisp={
death=function() death=function()
mStr(P.cstat.row.."/"..gameEnv.target,-75,250) mStr(P.cstat.row.."/"..gameEnv.target,-75,250)
end, end,
tetris25=function() tetris21=function()
gc.print("Remain",-140,450) gc.print("Remain",-140,450)
gc.print("Attack",-130,305) gc.print("Attack",-130,305)
setFont(80) setFont(80)
@@ -554,9 +571,11 @@ setting={
sfx=true,bgm=true, sfx=true,bgm=true,
fullscreen=false, fullscreen=false,
lang="eng", lang="eng",
das=5,arr=0, das=10,arr=2,
sddas=0,sdarr=2,
ghost=true,center=true, ghost=true,center=true,
key={"left","right","x","z","c","up","down","space","r","LEFT","RIGHT"}, key={"left","right","x","z","c","up","down","space","r","LEFT","RIGHT"},
gamepad={"dpleft","dpright","a","b","y","dpup","dpdown","rightshoulder","leftshoulder","LEFT","RIGHT"},
} }
stat={ stat={
run=0, run=0,
@@ -612,11 +631,35 @@ function mouseConvert(x,y)
return x*1280/ww,360+(y-wh*.5)*1280/ww return x*1280/ww,360+(y-wh*.5)*1280/ww
end end
end end
function sysSFX(s,v)
if setting.sfx then
local n=1
while sfx[s][n]:isPlaying()do
n=n+1
if not sfx[s][n]then
sfx[s][n]=sfx[s][n-1]:clone()
sfx[s][n]:seek(0)
end
end
sfx[s][n]:setVolume(v or 1)
sfx[s][n]:play()
end
end
function SFX(s,v) function SFX(s,v)
if setting.sfx then if setting.sfx then
sfx[s]:stop() local n=1
sfx[s]:setVolume(v or 1) while sfx[s][n]:isPlaying()do
sfx[s]:play() n=n+1
if not sfx[s][n]then
sfx[s][n]=sfx[s][n-1]:clone()
sfx[s][n]:seek(0)
end
end
if P.id>1 then
v=1/(#players.alive-1)
end
sfx[s][n]:setVolume(v or 1)
sfx[s][n]:play()
end end
end end
function BGM(s) function BGM(s)
@@ -640,6 +683,7 @@ function gotoScene(s,style)
end end
end end
function resetGameData() function resetGameData()
if players then restockRow()end--Avoid first start game error
players={alive={}} players={alive={}}
loadmode[gamemode]() loadmode[gamemode]()
@@ -652,6 +696,11 @@ function resetGameData()
PTC.dust[i]:start() PTC.dust[i]:start()
end end
stat.game=stat.game+1 stat.game=stat.game+1
freeRow={}
for i=1,50*#players do
freeRow[i]={0,0,0,0,0,0,0,0,0,0}
end
collectgarbage() collectgarbage()
end end
function startGame(mode) function startGame(mode)
@@ -691,9 +740,9 @@ function loaddata()
for i=#v+1,8 do v[i]="N/A"end for i=#v+1,8 do v[i]="N/A"end
setting.key=v setting.key=v
--Settings --Settings
elseif t=="das"or t=="arr"then elseif t=="das"or t=="arr"or t=="sddas"or t=="sdarr"then
v=toN(v)if not v or v<0 then v=0 end v=toN(v)if not v or v<0 then v=0 end
setting[t]=v setting[t]=int(v)
elseif t=="ghost"or t=="center"then elseif t=="ghost"or t=="center"then
setting[t]=v=="true" setting[t]=v=="true"
elseif t=="run"or t=="game"or t=="gametime"or t=="piece"or t=="row"or t=="atk"or t=="key"or t=="rotate"or t=="hold"or t=="spin"then elseif t=="run"or t=="game"or t=="gametime"or t=="piece"or t=="row"or t=="atk"or t=="key"or t=="rotate"or t=="hold"or t=="spin"then
@@ -723,6 +772,8 @@ function savedata()
t=t..stringPack("spin=",stat.spin) t=t..stringPack("spin=",stat.spin)
t=t..stringPack("das=",setting.das) t=t..stringPack("das=",setting.das)
t=t..stringPack("arr=",setting.arr) t=t..stringPack("arr=",setting.arr)
t=t..stringPack("sddas=",setting.sddas)
t=t..stringPack("sdarr=",setting.sdarr)
t=t..stringPack("keyset=",string.concat(setting.key)) t=t..stringPack("keyset=",string.concat(setting.key))
--t=love.math.compress(t,"zlib"):getString() --t=love.math.compress(t,"zlib"):getString()
userdata:open("w") userdata:open("w")
@@ -1081,7 +1132,7 @@ end
function lock() function lock()
for i=1,r do for i=1,r do
local y=cy+i-1 local y=cy+i-1
if not P.field[y]then P.field[y],P.visTime[y]={0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0}end if not P.field[y]then P.field[y],P.visTime[y]=getNewRow(),getNewRow()end
for j=1,c do for j=1,c do
if cb[i][j]~=0 then if cb[i][j]~=0 then
P.field[y][cx+j-1]=P.bn P.field[y][cx+j-1]=P.bn
@@ -1106,8 +1157,8 @@ function garbageRelease()
local atk=P.atkBuffer[i] local atk=P.atkBuffer[i]
if not atk.sent and atk.countdown==0 then if not atk.sent and atk.countdown==0 then
for j=1,atk.amount do for j=1,atk.amount do
ins(P.field,1,{13,13,13,13,13,13,13,13,13,13}) ins(P.field,1,getNewRow(13))
ins(P.visTime,1,{t,t,t,t,t,t,t,t,t,t}) ins(P.visTime,1,getNewRow(t))
for k=1,#atk do for k=1,#atk do
P.field[1][atk[k]]=0 P.field[1][atk[k]]=0
end end
@@ -1138,10 +1189,13 @@ end
function keyDown.setting2(key) function keyDown.setting2(key)
if key=="escape"then if key=="escape"then
back() back()
keysetting,gamepadsetting=nil
elseif keysetting then elseif keysetting then
setting.key[keysetting]=key setting.key[keysetting]=key
keysetting,gamepadsetting=nil
else
buttonControl_key(key)
end end
keysetting=nil
end end
keyUp={} keyUp={}
function keyUp.play(key) function keyUp.play(key)
@@ -1153,7 +1207,40 @@ function keyUp.play(key)
end end
end end
end end
gamepadDown={}
function gamepadDown.play(key)
local k=players[1].gameEnv.gamepad
for i=1,11 do
if key==k[i]then
pressKey(i,players[1])
break
end
end
if key=="escape"then back()end
end
function gamepadDown.setting2(key)
if key=="back"then
back()
keysetting,gamepadsetting=nil
elseif gamepadsetting then
setting.gamepad[gamepadsetting]=key
keysetting,gamepadsetting=nil
else
buttonControl_gamepad(key)
end
end
gamepadUp={}
function gamepadUp.play(key)
local k=players[1].gameEnv.gamepad
for i=1,10 do
if key==k[i]then
releaseKey(i,players[1])
break
end
end
end
wheelmoved={} wheelmoved={}
--Warning,these are not system callbacks!
require("BGblock")--BG block module require("BGblock")--BG block module
require("ai")--AI module require("ai")--AI module
@@ -1252,7 +1339,10 @@ function love.draw()
numFont(20)gc.setColor(1,1,1) numFont(20)gc.setColor(1,1,1)
gc.print(tm.getFPS(),0,700) gc.print(tm.getFPS(),0,700)
gc.print(gcinfo(),0,670) gc.print(gcinfo(),0,680)
-- numFont(80)
-- gc.print(gcinfo(),400,370)
--if gcinfo()>500 then collectgarbage()end --if gcinfo()>500 then collectgarbage()end
end end
function love.resize(x,y) function love.resize(x,y)
@@ -1283,7 +1373,7 @@ function love.run()
tm.step() tm.step()
love.resize(1280,720) love.resize(1280,720)
game.load()--Launch game.load()--Launch
math.randomseed(os.time()*626)--true ultheur's naim! math.randomseed(os.time()*626)--true ultheur's I D!
-- while true do -- while true do
return function() return function()
love.event.pump() love.event.pump()

View File

@@ -109,7 +109,7 @@ end
function Pnt.main() function Pnt.main()
gc.setColor(1,1,1) gc.setColor(1,1,1)
setFont(30) setFont(30)
gc.print("Alpha 0.1.19727",370,150) gc.print("Alpha 0.1+",370,150)
gc.draw(img.title[setting.lang],30,30) gc.draw(img.title[setting.lang],30,30)
end end
function Pnt.play() function Pnt.play()
@@ -266,17 +266,18 @@ function Pnt.play()
setmetatable(_G,nil) setmetatable(_G,nil)
end end
function Pnt.setting2() function Pnt.setting2()
gc.setColor(1,1,1)
setFont(18)
mStr("softdropDAS:"..setting.sddas,828,138)
mStr("softdropARR:"..setting.sdarr,1043,138)
setFont(35) setFont(35)
gc.setColor(1,1,1) mStr("DAS:"..setting.das,828,73)
mStr("DAS:"..setting.das,830,72) mStr("ARR:"..setting.arr,1043,73)
mStr("ARR:"..setting.arr,1045,72)
gc.setColor(1,1,1)
for i=1,9 do for i=1,9 do
gc.printf(actName_show[i]..":",100,60*i-8,200,"right") gc.printf(actName_show[i]..":",0,60*i-8,180,"right")
end end
if keysetting then if keysetting or gamepadsetting then
setFont(35) gc.print("<<",keysetting and 380 or 670,60*(keysetting or gamepadsetting)-10)
gc.print("<<",550,60*keysetting-10)
end end
end end
function Pnt.help() function Pnt.help()

View File

@@ -22,7 +22,7 @@ function Tmr.load()
end end
elseif loading==3 then elseif loading==3 then
if loadnum<=#sfx then if loadnum<=#sfx then
sfx[sfx[loadnum]]=love.audio.newSource("/SFX/"..sfx[loadnum]..".ogg","static") sfx[sfx[loadnum]]={love.audio.newSource("/SFX/"..sfx[loadnum]..".ogg","static")}
loadprogress=loadnum/#sfx loadprogress=loadnum/#sfx
loadnum=loadnum+1 loadnum=loadnum+1
else else
@@ -59,7 +59,7 @@ function Tmr.play(dt)
count=count-1 count=count-1
if count==0 then if count==0 then
count=nil count=nil
SFX("start") sysSFX("start")
for P=1,#players do for P=1,#players do
P=players[P] P=players[P]
_G.P=P _G.P=P
@@ -70,7 +70,7 @@ function Tmr.play(dt)
end end
setmetatable(_G,nil) setmetatable(_G,nil)
elseif count%60==0 then elseif count%60==0 then
SFX("ready") sysSFX("ready")
end end
if count then if count then
@@ -116,7 +116,6 @@ function Tmr.play(dt)
end end end end
--Fresh visible time --Fresh visible time
if keyPressing[1]or keyPressing[2]then if keyPressing[1]or keyPressing[2]then
P.moving=moving+sgn(moving)
local d=abs(moving)-gameEnv.das local d=abs(moving)-gameEnv.das
if d>1 then if d>1 then
if gameEnv.arr>0 then if gameEnv.arr>0 then
@@ -127,11 +126,21 @@ function Tmr.play(dt)
act[moving>0 and"toRight"or"toLeft"]() act[moving>0 and"toRight"or"toLeft"]()
end end
end end
P.moving=moving+sgn(moving)
else else
P.moving=0 P.moving=0
end end
if keyPressing[7]then if keyPressing[7]then
act.softDrop() local d=abs(downing)-gameEnv.sddas
if d>1 then
if gameEnv.sdarr>0 then
if d%gameEnv.sdarr==0 then
act.down1()
end
else
act.toDown()
end
end
P.downing=downing+1 P.downing=downing+1
else else
P.downing=0 P.downing=0
@@ -141,8 +150,8 @@ function Tmr.play(dt)
if falling<=0 then if falling<=0 then
if #field>clearing[1]then SFX("fall")end if #field>clearing[1]then SFX("fall")end
for i=1,#clearing do for i=1,#clearing do
rem(field,clearing[i]) removeRow(field,clearing[i])
rem(visTime,clearing[i]) removeRow(visTime,clearing[i])
end end
P.clearing={} P.clearing={}
end end
@@ -176,8 +185,8 @@ function Tmr.play(dt)
if falling<=0 then if falling<=0 then
if #field>clearing[1]then SFX("fall")end if #field>clearing[1]then SFX("fall")end
for i=1,#clearing do for i=1,#clearing do
rem(field,clearing[i]) removeRow(field,clearing[i])
rem(visTime,clearing[i]) removeRow(visTime,clearing[i])
end end
P.clearing={} P.clearing={}
end end
@@ -206,7 +215,7 @@ function Tmr.play(dt)
end end
end end
end end
if fieldBeneath>0 then P.fieldBeneath=fieldBeneath-2 end if fieldBeneath>0 then P.fieldBeneath=fieldBeneath-3 end
P.b2b1=P.b2b1*.95+P.b2b*.05 P.b2b1=P.b2b1*.95+P.b2b*.05
PTC.dust[p]:update(dt) PTC.dust[p]:update(dt)
end end

View File

@@ -31,7 +31,7 @@ act={
end end
end, end,
softDrop=function() softDrop=function()
act.toDown() if cy~=y_img then P.cy=cy-1 end
P.downing=1 P.downing=1
end, end,
rotRight=function()spin(1)end, rotRight=function()spin(1)end,
@@ -43,8 +43,8 @@ act={
resetGameData() resetGameData()
count=60+26--Althour'z neim count=60+26--Althour'z neim
end, end,
down1=function()drop()end, down1=function()if cy~=y_img then P.cy=cy-1 end end,
down4=function()for i=1,4 do if cy~=y_img then drop()else break end end end, down4=function()for i=1,4 do if cy~=y_img then P.cy=cy-1 else break end end end,
toDown=function()if cy~= y_img then P.cy,P.lockDelay,P.spinLast=y_img,gameEnv.lock,false end end, toDown=function()if cy~= y_img then P.cy,P.lockDelay,P.spinLast=y_img,gameEnv.lock,false end end,
toLeft=function()while not ifoverlap(cb,cx-1,cy)do P.cx,P.lockDelay=cx-1,gameEnv.lock;freshgho()end end, toLeft=function()while not ifoverlap(cb,cx-1,cy)do P.cx,P.lockDelay=cx-1,gameEnv.lock;freshgho()end end,
toRight=function()while not ifoverlap(cb,cx+1,cy)do P.cx,P.lockDelay=cx+1,gameEnv.lock;freshgho()end end, toRight=function()while not ifoverlap(cb,cx+1,cy)do P.cx,P.lockDelay=cx+1,gameEnv.lock;freshgho()end end,