Compare commits

...

4 Commits
v0.4 ... v0.6.8

Author SHA1 Message Date
MrZ_26
bdee7fba03 Alpha V0.6.8 2020-02-04 19:28:44 +08:00
MrZ_26
d8cbfa72ac Alpha V0.6.5 2020-02-04 19:28:33 +08:00
MrZ_26
31fd2c0e72 Alpha V0.6 2020-02-04 19:28:01 +08:00
MrZ_26
383254bce2 Alpha V0.5 2020-02-04 19:27:40 +08:00
27 changed files with 2223 additions and 1741 deletions

BIN
BGM/infinite.ogg Normal file

Binary file not shown.

View File

@@ -1,14 +0,0 @@
local count=0
BGblockList={}for i=1,16 do BGblockList[i]={}end
function getNewBlock()
count=count+1
if count==17 then count=1 end
local t=BGblockList[count]
t.bn,t.size=rnd(7),2+3*rnd()
t.b=blocks[t.bn][rnd(0,3)]
t.x=rnd(-#t.b[1]*t.size*30+100,1180)
t.y=-#t.b*30*t.size
t.v=t.size*(1+rnd())
return t
end

Binary file not shown.

BIN
SFX/fail.ogg Normal file

Binary file not shown.

BIN
SFX/win.ogg Normal file

Binary file not shown.

78
TRS.lua
View File

@@ -1,78 +0,0 @@
blocks={
{[0]={{0,1,1},{1,1,0}},{{1,0},{1,1},{0,1}},{{0,1,1},{1,1,0}},{{1,0},{1,1},{0,1}}},--Z
{[0]={{1,1,0},{0,1,1}},{{0,1},{1,1},{1,0}},{{1,1,0},{0,1,1}},{{0,1},{1,1},{1,0}}},--S
{[0]={{1,1,1},{0,0,1}},{{1,1},{1,0},{1,0}},{{1,0,0},{1,1,1}},{{0,1},{0,1},{1,1}}},--L
{[0]={{1,1,1},{1,0,0}},{{1,0},{1,0},{1,1}},{{0,0,1},{1,1,1}},{{1,1},{0,1},{0,1}}},--J
{[0]={{1,1,1},{0,1,0}},{{1,0},{1,1},{1,0}},{{0,1,0},{1,1,1}},{{0,1},{1,1},{0,1}}},--T
{[0]={{1,1},{1,1}},{{1,1},{1,1}},{{1,1},{1,1}},{{1,1},{1,1}}},--O
{[0]={{1,1,1,1}},{{1},{1},{1},{1}},{{1,1,1,1}},{{1},{1},{1},{1}}},--I
}
do
scs={
{[0]={1,2},{2,1},{2,2},{2,2}},
{[0]={1,2},{2,1},{2,2},{2,2}},
{[0]={1,2},{2,1},{2,2},{2,2}},
{[0]={1,2},{2,1},{2,2},{2,2}},
{[0]={1,2},{2,1},{2,2},{2,2}},
{[0]={1.5,1.5},{1.5,1.5},{1.5,1.5},{1.5,1.5},},
{[0]={.5,2.5},{2.5,0.5},{1.5,2.5},{2.5,1.5}},
}
TRS={
[1]={
[01]={{0,0},{-1,0},{-1,1},{0,-2},{-1,-2},{0,1}},
[10]={{0,0},{1,0},{1,-1},{0,2},{1,2},{0,-1}},
[12]={{0,0},{1,0},{1,-1},{0,2},{1,2}},
[21]={{0,0},{-1,0},{-1,1},{0,-2},{-1,-2}},
[23]={{0,0},{1,0},{1,1},{0,-2},{1,-2}},
[32]={{0,0},{-1,0},{-1,-1},{0,2},{-1,2}},
[30]={{0,0},{-1,0},{-1,-1},{0,2},{-1,2}},
[03]={{0,0},{1,0},{1,1},{0,-2},{1,-2}},
[02]={{0,0},{1,0},{-1,0},{0,-1},{0,1}},
[20]={{0,0},{-1,0},{1,0},{0,1},{0,-1}},
[13]={{0,0},{0,1},{0,-1},{-1,0},{1,0},{0,2}},
[31]={{0,0},{0,-1},{0,1},{1,0},{-1,0},{0,2}},
},
[2]={
[01]={{0,0},{-1,0},{-1,1},{0,-2},{-1,-2}},
[10]={{0,0},{1,0},{1,-1},{0,2},{1,2}},
[12]={{0,0},{1,0},{1,-1},{0,2},{1,2}},
[21]={{0,0},{-1,0},{-1,1},{0,-2},{-1,-2}},
[23]={{0,0},{1,0},{1,1},{0,-2},{1,-2}},
[32]={{0,0},{-1,0},{-1,-1},{0,2},{-1,2}},
[30]={{0,0},{-1,0},{-1,-1},{0,2},{-1,2},{0,-1}},
[03]={{0,0},{1,0},{1,1},{0,-2},{1,-2},{0,1}},
[02]={{0,0},{-1,0},{1,0},{0,-1},{0,1}},
[20]={{0,0},{1,0},{-1,0},{0,1},{0,-1}},
[13]={{0,0},{0,-1},{0,1},{1,0},{-1,0},{0,2}},
[31]={{0,0},{0,1},{0,-1},{-1,0},{1,0},{0,2}},
},
[5]={
[01]={{0,0},{-1,0},{-1,1},{0,-2},{-1,-2}},
[10]={{0,0},{1,0},{1,-1},{0,2},{1,2},{0,-1}},
[12]={{0,0},{1,0},{1,-1},{0,2},{1,2}},
[21]={{0,0},{-1,0},{-1,1},{0,-2},{-1,-2}},
[23]={{0,0},{1,0},{1,1},{0,-2},{1,-2}},
[32]={{0,0},{-1,0},{-1,-1},{0,2},{-1,2}},
[30]={{0,0},{-1,0},{-1,-1},{0,2},{-1,2},{0,-1}},
[03]={{0,0},{1,0},{1,1},{0,-2},{1,-2},{0,1}},
[02]={{0,0},{-1,0},{1,0},{0,-1},{0,1}},
[20]={{0,0},{1,0},{-1,0},{0,1},{0,-1}},
[13]={{0,0},{0,-1},{0,1},{1,0},{-1,0},{0,2}},
[31]={{0,0},{0,-1},{0,1},{-1,0},{1,0},{0,2}},
},
[7]={
[01]={{0,0},{-2,0},{1,0},{-2,-1},{1,2}},
[10]={{0,0},{2,0},{-1,0},{2,1},{-1,-2}},
[12]={{0,0},{-1,0},{2,0},{-1,2},{2,-1}},
[21]={{0,0},{1,0},{-2,0},{1,-2},{-2,1}},
[23]={{0,0},{2,0},{-1,0},{2,1},{-1,-2}},
[32]={{0,0},{-2,0},{1,0},{-2,-1},{1,2}},
[30]={{0,0},{1,0},{-2,0},{1,-2},{-2,1}},
[03]={{0,0},{-1,0},{2,0},{-1,2},{2,-1}},
[02]={{0,0},{-1,0},{1,0},{0,-1},{0,1}},
[20]={{0,0},{1,0},{-1,0},{0,1},{0,-1}},
[13]={{0,0},{0,-1},{-1,0},{1,0},{0,1}},
[31]={{0,0},{0,-1},{1,0},{-1,0},{0,1}},
}
}TRS[3],TRS[4],TRS[6]=TRS[2],TRS[1],TRS[1]
end

51
ai.lua
View File

@@ -18,7 +18,33 @@ spinOffset={
{0,0,0},--O
{2,0,1},--I
}for i=1,7 do spinOffset[i][0]=0 end
--[[controlname:
1~5:mL,mR,rR,rL,rF,
6~9:hD,sD,H,R,
10~12:LL,RR,DD
]]
FCL={
[1]={
{{10},{10,2},{1},{},{2},{2,2},{11,1},{11}},
{{10,4},{10,3},{10,2,3},{4},{3},{2,3},{2,2,3},{11,4},{11,3}},
},
[3]={
{{10},{10,2},{1},{},{2},{2,2},{11,1},{11},},
{{3,10},{10,3},{10,2,3},{1,3},{3},{2,3},{2,2,3},{11,1,3},{11,3},},
{{10,5},{10,2,5},{1,5},{5},{2,5},{2,2,5},{11,1,5},{11,5},},
{{10,4},{10,2,4},{1,4},{4},{2,4},{2,2,4},{11,1,4},{11,4},{4,11},},
},
[6]={
{{10},{10,2},{1,1},{1},{},{2},{2,2},{11,1},{11},},
},
[7]={
{{10},{10,2},{1},{},{2},{11,1},{11},},
{{4,10},{10,4},{10,3},{1,4},{4},{3},{2,3},{11,4},{11,3},{3,11},},
},
}
FCL[2]=FCL[1]
FCL[4]=FCL[3]
FCL[5]=FCL[3]
function ifoverlapAI(f,bk,x,y)
if y<1 then return true end
if y>#f then return nil end
@@ -83,7 +109,6 @@ function getScore(field,cb,cx,cy)
+clear^2*4
-hole*15
end
--controlname:mL,mR,rR,rL,rF,hD,sD,H,LL,RR
function AI_getControls(ctrl)
local Tfield={}--test field
local field_org=field
@@ -96,9 +121,9 @@ function AI_getControls(ctrl)
local best={x=1,dir=0,hold=false,score=-9e99}
for ifhold=0,1 do
local bn=ifhold==0 and bn or hn>0 and hn or nxt[1]
for dir=0,dirCount[bn] do--for each direction
for dir=0,dirCount[bn] do--each dir
local cb=blocks[bn][dir]
for cx=1,11-#cb[1]do--for each positioon
for cx=1,11-#cb[1]do--each pos
local cy=#Tfield+1
while not ifoverlapAI(Tfield,cb,cx,cy-1)do
cy=cy-1
@@ -128,17 +153,11 @@ function AI_getControls(ctrl)
if best.hold then
ins(ctrl,8)
end
if best.dir==1 then
ins(ctrl,3)
elseif best.dir==2 then
ins(ctrl,5)
elseif best.dir==3 then
ins(ctrl,4)
end--hold&rotate
best.x=best.x-spinOffset[best.bn][best.dir]
local n=blockPos[best.bn]<best.x and 2 or 1
for i=1,abs(blockPos[best.bn]-best.x)do
ins(ctrl,n)
end--move
local l=FCL[best.bn][best.dir+1][best.x]
for i=1,#l do
ins(ctrl,l[i])
end
ins(ctrl,6)--harddrop
end

View File

@@ -1,139 +0,0 @@
Buttons={
load={},
intro={},
main={
{x=250,y=300,w=330,h=60,rgb=color.red,t="Play",code=function()gotoScene("mode")end,down=2},
{x=250,y=380,w=330,h=60,rgb=color.blue,t="Settings",code=function()gotoScene("setting")end,up=1,down=3},
{x=165,y=460,w=160,h=60,rgb=color.yellow,t="Help",code=function()gotoScene("help")end,up=2,down=5,right=4},
{x=335,y=460,w=160,h=60,rgb=color.cyan,t="Statistics",code=function()gotoScene("stat")end,up=2,down=5,left=3},
{x=250,y=540,w=330,h=60,rgb=color.grey,t="Quit",code=function()gotoScene("quit")end,up=3},
},
mode={
{x=330,y=140,w=280,h=70,rgb=color.white,t="40 Lines",code=function()startGame("sprint")end,down=4,right=2},
{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=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 41",code=function()startGame("tetris41")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=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=950,y=360,w=280,h=70,rgb=color.white,t="Asymmetry Solo",code=function()startGame("asymsolo")end,up=6,down=10,left=8},
{x=640,y=590,w=180,h=60,rgb=color.white,t="Back",code=function()gotoScene("main")end,up=8},
},
play={
},
setting={--Normal setting
{x=330,y=100,w=200,h=60,rgb=color.white,t=function()return setting.ghost and"Ghost ON"or"Ghost OFF"end,code=function()setting.ghost=not setting.ghost end,down=6,right=2},
{x=540,y=100,w=200,h=60,rgb=color.white,t=function()return setting.center and"Center ON"or"Center OFF"end,code=function()setting.center=not setting.center end,down=6,left=1,right=3},
{x=870,y=100,w=340,h=60,rgb=color.white,t=function()return setting.sfx and"Disable SFX"or"Enable SFX"end,code=function()setting.sfx=not setting.sfx end,down=4,left=2},
{x=870,y=180,w=340,h=60,rgb=color.white,t=function()return setting.bgm and"Disable BGM"or"Enable BGM"end,code=function()BGM()setting.bgm=not setting.bgm;BGM("blank")end,up=3,down=5,left=2},
{x=870,y=260,w=340,h=60,rgb=color.white,t=function()return setting.fullscreen and"Disable fullscreen"or"Enable fullscreen"end,
code=function()
setting.fullscreen=not setting.fullscreen
love.window.setFullscreen(setting.fullscreen)
end,
up=4,down=7,left=6
},
{x=435,y=220,w=320,h=60,rgb=color.green,t="Advanced settings",code=function()gotoScene("setting2")end,up=1,down=7,right=5},
{x=435,y=300,w=320,h=60,rgb=color.yellow,t="Touch settings",code=function()gotoScene("setting3")end,up=6,down=8,right=5},
{x=640,y=590,w=210,h=60,rgb=color.white,t="Save&Back",code=function()back()end,up=6},
},
setting2={--Advanced setting
{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=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=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=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=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=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=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=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=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},
--1~9
{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=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=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=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=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=23},
{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,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,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,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,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,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,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,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,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=24,left=27},
--27~28
},
setting3={--Touch setting
{x=640,y=210,w=400,h=80,rgb=color.white,t=function()return setting.virtualkeySwitch and"Hide Virtual Key"or"Show Virtual Key"end,code=function()
setting.virtualkeySwitch=not setting.virtualkeySwitch
end},
{x=500,y=310,w=120,h=80,rgb=color.white,t="Reset",code=function()
for K=1,#virtualkey do
local b,b0=virtualkey[K],gameEnv0.virtualkey[K]
b[1],b[2],b[3],b[4]=b0[1],b0[2],b0[3],b0[4]
end--Reset virtualkey
end},
{x=640,y=310,w=120,h=80,rgb=color.white,t="Snap",code=function()
for K=1,#virtualkey do
local b=virtualkey[K]
b[1],b[2]=int(b[1]*.025+.5)*40,int(b[2]*.025+.5)*40
end--Snap all keys
end},
{x=780,y=310,w=120,h=80,rgb=color.white,t=function()return percent0to5[setting.virtualkeyAlpha]end,code=function()
setting.virtualkeyAlpha=(setting.virtualkeyAlpha+1)%6
--Adjust virtualkey alpha
end},
{x=500,y=410,w=120,h=80,rgb=color.white,t="Icon",code=function()
setting.virtualkeyIcon=not setting.virtualkeyIcon
--Switch virtualkey icon
end},
{x=640,y=410,w=120,h=80,rgb=color.white,t="Back",code=function()back()end},
{x=780,y=410,w=120,h=80,rgb=color.white,t="Size",code=function()
for K=1,#virtualkey do
local b=virtualkey[K]
b[4]=b[4]+10
if b[4]==150 then b[4]=40 end
b[3]=b[4]^2
end
end},
},
help={
{x=640,y=590,w=180,h=60,rgb=color.white,t="Back",code=function()back()end},
},
stat={
{x=640,y=590,w=180,h=60,rgb=color.white,t="Back",code=function()back()end},
},
sel=nil,--selected button id(integer)
}
for k,v in pairs(Buttons)do
for i=1,#v do
v[i].alpha=0
end
end
virtualkey={
{80,720-80,6400,80},--moveLeft
{240,720-80,6400,80},--moveRight
{1280-240,720-80,6400,80},--rotRight
{1280-400,720-80,6400,80},--rotLeft
{1280-240,720-240,6400,80},--rotFlip
{1280-80,720-80,6400,80},--hardDrop
{1280-80,720-240,6400,80},--softDrop
{1280-80,720-400,6400,80},--hold
{80,80,6400,80},--restart
--[[
{x=0,y=0,r=0},--toLeft
{x=0,y=0,r=0},--toRight
{x=0,y=0,r=0},--toDown
]]
}

487
call&sys.lua Normal file
View File

@@ -0,0 +1,487 @@
function onVirtualkey(x,y)
local x,y=convert(x,y)
local d2,nearest,distance
for K=1,#virtualkey do
local b=virtualkey[K]
d2=(x-b[1])^2+(y-b[2])^2
if d2<b[3]then
if not nearest or d2<distance then
nearest,distance=K,d2
end
end
end
return nearest
end
function buttonControl_key(i)
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
mouseShow=false
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]
B.code()
B.alpha=1
sysSFX("button")
end
end
mouseShow=false
end
mouseDown={}
keyDown={}
function keyDown.mode(key)
if key=="down"then
if modeSel<#modeID then modeSel=modeSel+1 end
elseif key=="up"then
if modeSel>1 then modeSel=modeSel-1 end
elseif key=="return"then
startGame(modeID[modeSel])
elseif key=="escape"then
back()
end
end
function keyDown.setting2(key)
if key=="escape"then
if keyboardSetting then
keyboardSetting=false
else
back()
end
elseif keyboardSetting then
for l=1,8 do
for y=1,12 do
if setting.keyMap[l][y]==key then
setting.keyMap[l][y]=""
end
end
end
setting.keyMap[curBoard][keyboardSet]=key
keyboardSetting=false
elseif key=="return"then
keyboardSetting=true
elseif key=="up"then
keyboardSet=max(keyboardSet-1,1)
elseif key=="down"then
keyboardSet=min(keyboardSet+1,12)
elseif key=="left"then
curBoard=max(curBoard-1,1)
elseif key=="right"then
curBoard=min(curBoard+1,8)
end
end
function keyDown.play(key)
if key=="escape"then back()return nil end
local m=setting.keyMap
for p=1,4 do
local lib=setting.keyLib[p]
for s=1,#lib do
for k=1,12 do
if key==m[lib[s]][k]then
pressKey(k,players[p])
return nil
end
end
end
end
end
keyUp={}
function keyUp.play(key)
local m=setting.keyMap
for p=1,4 do
local lib=setting.keyLib[p]
for s=1,#lib do
for k=1,12 do
if key==m[lib[s]][k]then
releaseKey(k,players[p])
return nil
end
end
end
end
end
gamepadDown={}
function gamepadDown.mode(key)
if key=="dpdown"then
if modeSel<#modeID then modeSel=modeSel+1 end
elseif key=="dpup"then
if modeSel>1 then modeSel=modeSel-1 end
elseif key=="start"then
startGame(modeID[modeSel])
elseif key=="back"then
back()
end
end
function gamepadDown.setting2(key)
if key=="back"then
if joystickSetting then
joystickSetting=false
else
back()
end
elseif joystickSetting then
for l=9,16 do
for y=1,12 do
if setting.keyMap[l][y]==key then
setting.keyMap[l][y]=""
end
end
end
setting.keyMap[8+curBoard][joystickSet]=key
joystickSetting=false
elseif key=="start"then
joystickSetting=true
elseif key=="up"then
joystickSet=max(joystickSet-1,1)
elseif key=="down"then
joystickSet=min(joystickSet+1,12)
elseif key=="left"then
curBoard=max(curBoard-1,1)
elseif key=="right"then
curBoard=min(curBoard+1,8)
end
end
function gamepadDown.play(key)
if key=="back"then back()return nil end
local m=setting.keyMap
for p=1,4 do
local lib=setting.keyLib[p]
for s=1,#l[p]do
for k=1,12 do
if key==m[8+lib[s]][k]then
pressKey(k)
return nil
end
end
end
end
end
gamepadUp={}
function gamepadUp.play(key)
local m=setting.keyMap
for p=1,4 do
local lib=setting.keyLib[p]
for s=1,#l[p]do
for k=1,12 do
if key==m[8+lib[s]][k]then
pressKey(k)
return nil
end
end
end
end
end
wheelmoved={}
function wheelmoved.mode(x,y)
modeSel=min(max(modeSel-sgn(y),1),#modeID)
end
--Warning,these are not system callbacks!
function love.mousemoved(x,y,dx,dy,t)
if not t then
mouseShow=true
mx,my=convert(x,y)
Buttons.sel=nil
for i=1,#Buttons[scene]do
local B=Buttons[scene][i]
if not(B.hide and B.hide())then
if abs(mx-B.x)<B.w*.5 and abs(my-B.y)<B.h*.5 then
Buttons.sel=i
return nil
end
end
end
end
end
function love.mousepressed(x,y,k,t,num)
if not t then
mouseShow=true
mx,my=convert(x,y)
if mouseDown[scene]then mouseDown[scene](mx,my,k)end
if k==1 then
if not sceneSwaping and Buttons.sel then
local B=Buttons[scene][Buttons.sel]
B.code()
B.alpha=1
Buttons.sel=nil
love.mousemoved(x,y)
sysSFX("button")
end
elseif k==3 then
back()
end
end
end
function love.mousereleased(x,y,k,t,num)
end
function love.touchpressed(id,x,y)
if not touching then
touching=id
love.mousemoved(x,y)
mouseShow=false
end
if scene=="play"and setting.virtualkeySwitch then
local t=onVirtualkey(x,y)
if t then
pressKey(t,players[1])
end
elseif scene=="setting3"then
x,y=convert(x,y)
for K=1,#virtualkey do
local b=virtualkey[K]
if (x-b[1])^2+(y-b[2])^2<b[3]then
sel=K
end
end
end
end
function love.touchreleased(id,x,y)
if id==touching then
touching=nil
if Buttons.sel then
local B=Buttons[scene][Buttons.sel]
B.code()
B.alpha=1
Buttons.sel=nil
end
Buttons.sel=nil
mouseShow=false
end
if scene=="play"and setting.virtualkeySwitch then
local t=onVirtualkey(x,y)
if t then
releaseKey(t)
end
elseif scene=="setting3"and sel then
x,y=convert(x,y)
if sel then
local b=virtualkey[sel]
local k=snapLevelValue[snapLevel]
b[1],b[2]=int(b[1]/k+.5)*k,int(b[2]/k+.5)*k
end
end
end
function love.touchmoved(id,x,y,dx,dy)
love.mousemoved(x,y)
mouseShow=false
if not Buttons.sel then
touching=nil
end
if scene=="play"and setting.virtualkeySwitch then
local l=tc.getTouches()
for n=1,#virtualkey do
local b=virtualkey[n]
local p=false
for i=1,#l do
local x,y=convert(tc.getPosition(l[i]))
if(x-b[1])^2+(y-b[2])^2<=b[3]then
p=true
break
end
end
if not p and players[1].keyPressing then
releaseKey(n)
end
end
elseif scene=="setting3"then
x,y=convert(x,y)
dx,dy=dx*screenK,dy*screenK
if sel then
local b=virtualkey[sel]
b[1],b[2]=b[1]+dx,b[2]+dy
end
end
end
function love.keypressed(i)
if keyDown[scene]then keyDown[scene](i)
elseif i=="escape"or i=="back"then back()
else buttonControl_key(i)
end
if i=="f12"then devMode=true end
end
function love.keyreleased(i)
if keyUp[scene]then keyUp[scene](i)
end
end
function love.gamepadpressed(joystick,i)
if gamepadDown[scene]then return gamepadDown[scene](i)
elseif i=="back"then return back()
else buttonControl_gamepad(i)
end
end
function love.gamepadreleased(joystick,i)
if gamepadUp[scene]then gamepadUp[scene](i)
end
end
--[[
function love.joystickpressed(js,k)
end
function love.joystickaxis(js,axis,val)
end
function love.joystickhat(js,hat,dir)
end
]]
function love.wheelmoved(x,y)
if wheelmoved[scene]then wheelmoved[scene](x,y)end
end
function love.update(dt)
--[[
if players then
for k,v in pairs(players[1])do
if rawget(_G,k)then print(k)end
end
end--check player data flew(debugging)
]]
for i=#BGblock,1,-1 do
BGblock[i].y=BGblock[i].y+BGblock[i].v
if BGblock[i].y>720 then rem(BGblock,i)end
end
if setting.bgblock then
BGblock.ct=BGblock.ct-1
if BGblock.ct==0 then
ins(BGblock,getNewBlock())
BGblock.ct=rnd(20,30)
end
end
--Background blocks update
if sceneSwaping then
sceneSwaping.time=sceneSwaping.time-1
if sceneSwaping.time==sceneSwaping.mid then
for i=1,#Buttons[scene]do
Buttons[scene][i].alpha=0
end--Reset buttons' state
game[sceneSwaping.tar]()
Buttons.sel=nil
elseif sceneSwaping.time==0 then
sceneSwaping=nil
end
elseif Tmr[scene]then
Tmr[scene](dt)
end
--scene swapping & Timer
end
function love.sendData(data)
return nil
end
function love.receiveData(id,data)
return nil
end
function love.draw()
Pnt.BG[curBG]()
gc.setColor(1,1,1,.3)
for n=1,#BGblock do
local b,img=BGblock[n].b,blockSkin[BGblock[n].bn]
local size=BGblock[n].size
for i=1,#b do for j=1,#b[1]do
if b[i][j]>0 then
gc.draw(img,BGblock[n].x+(j-1)*30*size,BGblock[n].y+(i-1)*30*size,nil,size)
end
end end--Block
end
if Pnt[scene]then Pnt[scene]()end
drawButton()
if mouseShow and not touching then
gc.setColor(1,1,1)
gc.draw(mouseIcon,mx,my,nil,nil,nil,10,10)
end
if sceneSwaping then sceneSwaping.draw()end
gc.setColor(0,0,0)
if screenM>0 then
gc.rectangle("fill",0,0,1280,-screenM)
gc.rectangle("fill",0,720,1280,screenM)
end--Draw black side
setFont(20)gc.setColor(1,1,1)
gc.print(tm.getFPS(),0,700)
if devMode then
gc.print(gcinfo(),0,680)
gc.print(freeRow and #freeRow or 0,0,660)
end
--if gcinfo()>500 then collectgarbage()end
end
function love.resize(x,y)
screenK=1280/gc.getWidth()
screenM=(gc.getHeight()*16/9-gc.getWidth())/2
gc.origin()
gc.scale(1/screenK,1/screenK)
gc.translate(0,screenM)
end
function love.run()
local frameT=Timer()
local readyDrawFrame=0
tm.step()
love.resize(nil,gc.getHeight())
game.load()--System scene Launch
math.randomseed(os.time()*626)
return function()
love.event.pump()
for name,a,b,c,d,e,f in love.event.poll()do
if name=="quit"then return 0 end
love.handlers[name](a,b,c,d,e,f)
end
if focus then
tm.step()
-- love.receiveData(id,data)
love.update(tm.getDelta())
readyDrawFrame=readyDrawFrame+setting.frameMul
if readyDrawFrame>=100 then
readyDrawFrame=readyDrawFrame-100
gc.clear()
love.draw()
gc.present()
end
if not wd.hasFocus()then
focus=false
ms.setVisible(true)
if bgmPlaying then bgm[bgmPlaying]:pause()end
if scene=="play"then
for i=1,#players[1].keyPressing do
if players[1].keyPressing[i]then
releaseKey(i)
end
end
end
end
else
tm.sleep(.2)
if wd.hasFocus()then
focus=true
ms.setVisible(false)
if bgmPlaying then bgm[bgmPlaying]:play()end
end
end
while Timer()-frameT<1/60 do end
frameT=Timer()
end
end

View File

@@ -9,7 +9,7 @@ function love.conf(t)
t.audio.mixwithsystem=true--Switch on to keep background music playing
local W=t.window
W.title="Techmino V0.4"
W.title="Techmino V0.68"
W.icon="/image/icon.png"
W.width,W.height=1280,720
W.borderless=X
@@ -17,10 +17,10 @@ function love.conf(t)
W.minwidth,W.minheight=640,360
W.fullscreentype="desktop"--Choose between "desktop" fullscreen or "exclusive" fullscreen mode (string)
W.fullscreen=X
W.vsync=1
W.vsync=X--0 to set ∞fps
W.msaa=X--The number of samples to use with multi-sampled antialiasing (number)
W.depth=X--The number of bits per sample in the depth buffer
W.stencil=1--The number of bits per sample in the stencil buffer
W.stencil=8--The number of bits per sample in the stencil buffer
W.display=1--Monitor ID
W.highdpi=X--Enable high-dpi mode for the window on a Retina display (boolean)
W.x,W.y=nil

View File

@@ -1,196 +0,0 @@
function onVirtualkey(x,y)
local x,y=convert(x,y)
local d2,nearest,distance
for K=1,#virtualkey do
local b=virtualkey[K]
d2=(x-b[1])^2+(y-b[2])^2
if d2<b[3]then
if not nearest or d2<distance then
nearest,distance=K,d2
end
end
end
return nearest
end
function buttonControl_key(i)
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
mouseShow=false
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]
B.code()
B.alpha=1
sysSFX("button")
end
end
mouseShow=false
end
function love.mousemoved(x,y,dx,dy,t)
if not t then
mouseShow=true
mx,my=convert(x,y)
Buttons.sel=nil
for i=1,#Buttons[scene]do
local B=Buttons[scene][i]
if not(B.hide and B.hide())then
if abs(mx-B.x)<B.w*.5 and abs(my-B.y)<B.h*.5 then
Buttons.sel=i
return nil
end
end
end
end
end
function love.mousepressed(x,y,k,t,num)
if not t then
mouseShow=true
mx,my=convert(x,y)
if mouseDown[scene]then mouseDown[scene](mx,my,k)end
if k==1 then
if not sceneSwaping and Buttons.sel then
local B=Buttons[scene][Buttons.sel]
B.code()
B.alpha=1
Buttons.sel=nil
love.mousemoved(x,y)
sysSFX("button")
end
elseif k==3 then
back()
end
end
end
function love.mousereleased(x,y,k,t,num)
end
function love.touchpressed(id,x,y)
if not touching then
touching=id
love.mousemoved(x,y)
mouseShow=false
end
if scene=="play"and setting.virtualkeySwitch then
local t=onVirtualkey(x,y)
if t then
pressKey(t)
end
end
end
function love.touchreleased(id,x,y)
if id==touching then
touching=nil
if Buttons.sel then
local B=Buttons[scene][Buttons.sel]
B.code()
B.alpha=1
Buttons.sel=nil
end
Buttons.sel=nil
mouseShow=false
end
if scene=="play"and setting.virtualkeySwitch then
local t=onVirtualkey(x,y)
if t then
releaseKey(t)
end
end
end
function love.touchmoved(id,x,y,dx,dy)
love.mousemoved(x,y)
mouseShow=false
if not Buttons.sel then
touching=nil
end
if scene=="play"and setting.virtualkeySwitch then
local l=tc.getTouches()
for n=1,#virtualkey do
local b=virtualkey[n]
local p=false
for i=1,#l do
local x,y=convert(tc.getPosition(l[i]))
if(x-b[1])^2+(y-b[2])^2<=b[3]then
p=true
break
end
end
if not p and players[1].keyPressing then
releaseKey(n)
end
end
elseif scene=="setting3"then
x,y=convert(x,y)
dx,dy=dx*screenK,dy*screenK
for K=1,#virtualkey do
local b=virtualkey[K]
if (x-b[1])^2+(y-b[2])^2<b[3]then
b[1],b[2]=b[1]+dx,b[2]+dy
end
end
end
end
function love.keypressed(i)
if keyDown[scene]then keyDown[scene](i)
elseif i=="escape"or i=="back"then back()
else buttonControl_key(i)
end
end
function love.keyreleased(i)
if keyUp[scene]then keyUp[scene](i)
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]
B.code()
B.alpha=1
sysSFX("button")
end
end
end
if gamepadDown[scene]then return gamepadDown[scene](i)
elseif i=="back"then return back()
else buttonControl_gamepad(i)
end
end
function love.gamepadreleased(joystick,i)
if gamepadUp[scene]then gamepadUp[scene](i)
end
end
function love.wheelmoved(x,y)
if wheelmoved[scene]then wheelmoved[scene](x,y)end
end

495
gamefunc.lua Normal file
View File

@@ -0,0 +1,495 @@
function resetGameData()
players={alive={}}
royaleMode=false
loadmode[gamemode]()
frame=0
count=179
FX.beam={}
for i=1,#PTC.dust do PTC.dust[i]:release()end
for i=1,#players do
PTC.dust[i]=PTC.dust[0]:clone()
PTC.dust[i]:start()
end
for i=1,#virtualkey do
virtualkey[i].press=false
end
stat.game=stat.game+1
freeRow={}
collectgarbage()
for i=1,50*#players do
freeRow[i]={0,0,0,0,0,0,0,0,0,0}
end
end
function createPlayer(id,x,y,size,AIspeed,data)
players[id]={id=id}
ins(players.alive,id)
local P=players[id]
P.index={__index=P}
P.x,P.y,P.size=x,y,size or 1
P.small=P.size<.3
if AIspeed then
P.ai={
controls={},
controlDelay=60,
controlDelay0=AIspeed,
}
end
P.alive=true
P.control=false
P.timing=false
P.time=0
P.cstat={key=0,piece=0,row=0,atk=0,tetris=0}--Current gamestat
P.keyTime={}for i=1,10 do P.keyTime[i]=-1e5 end P.keySpeed=0
P.dropTime={}for i=1,10 do P.dropTime[i]=-1e5 end P.dropSpeed=0
P.field,P.visTime,P.atkBuffer={},{},{}
P.badge,P.strength,P.lastRecv=0,0,nil
P.gameEnv={}--Game setting vars,like dropDelay setting
for k,v in pairs(gameEnv0)do
if data and data[k]~=nil then
P.gameEnv[k]=data[k]
elseif modeEnv[k]~=nil then
P.gameEnv[k]=modeEnv[k]
elseif setting[k]~=nil then
P.gameEnv[k]=setting[k]
else
P.gameEnv[k]=v
end
end--reset current game settings
P.hn,P.hb,P.holded=0,{{}},false
P.nxt,P.nb={},{}
P.dropDelay,P.lockDelay=P.gameEnv.drop,P.gameEnv.lock
P.freshTime=0
P.lastSpin=false
local bag1={1,2,3,4,5,6,7}
for i=1,7 do
P.nxt[i]=rem(bag1,rnd(#bag1))
P.nb[i]=blocks[P.nxt[i]][0]
end--First bag
if P.gameEnv.sequence==1 then P.bag={}--Bag7
elseif P.gameEnv.sequence==2 then P.his={}for i=1,4 do P.his[i]=P.nxt[i+3]end--History4
elseif P.gameEnv.sequence==3 then--Pure random
end
P.showTime=P.gameEnv.visible==1 and 1e99 or P.gameEnv.visible==2 and 300 or 20
P.freshNext=randomMethod[P.gameEnv.sequence]
P.cb,P.sc,P.bn,P.r,P.c,P.cx,P.cy,P.dir,P.y_img={{}},{0,0},1,0,0,0,0,0,0
P.keyPressing={}for i=1,12 do P.keyPressing[i]=false end
P.moving,P.downing=0,0
P.waiting,P.falling=0,0
P.clearing={}
P.fieldBeneath=0
P.combo=0
P.b2b=0
P.b2b1=0
P.counter=0
P.result=nil--string,"win"/"lose"
P.task={}
P.bonus={}
end
function showText(text,type,font,dy,inf)
if not P.small then
ins(P.bonus,{t=0,text=text,draw=FX[type],font=font,dy=dy or 0,inf=inf,solid=inf})
end
end
function createBeam(s,r,lv)--Player id
S,R=players[s],players[r]
local x1,y1,x2,y2
if S.small then
x1,y1=S.x+(30*(cx+sc[2]-1)+15)*S.size,S.y+(600-30*(cy+sc[1]-1)+15)*S.size
else
x1,y1=S.x+(30*(cx+sc[2]-1)-30+15+150)*S.size,S.y+(600-30*(cy+sc[1]-1)+15+70)*S.size
end
if R.small then
x2,y2=R.x+150*R.size,R.y+300*R.size
else
x2,y2=R.x+308*R.size,R.y+450*R.size
end
ins(FX.beam,{x1,y1,x2,y2,t=0,lv=lv})
end
function throwBadge(s,r,amount)--Player id
s,r=players[s],players[r]
local x1,y1,x2,y2
if s.small then
x1,y1=s.x+150*s.size,s.y+300*s.size
else
x1,y1=s.x+308*s.size,s.y+450*s.size
end
if r.small then
x2,y2=r.x+150*r.size,r.y+300*r.size
else
x2,y2=r.x+308*r.size,r.y+450*r.size
end
ins(FX.badge,{x1,y1,x2,y2,t=0,size=(10+min(amount,10))*.1})
end
function freshgho()
if P.gameEnv._20G or keyPressing[7]and gameEnv.sdarr==0 then
while not ifoverlap(cb,cx,cy-1)do
P.cy=P.cy-1
P.spinLast=false
end
P.y_img=P.cy
else
P.y_img=P.cy>#field+1 and #field+1 or P.cy
while not ifoverlap(cb,cx,y_img-1)do
P.y_img=P.y_img-1
end
end
end
function freshLockDelay()
if P.lockDelay<gameEnv.lock and P.freshTime<=gameEnv.freshLimit then
P.lockDelay=gameEnv.lock
P.freshTime=P.freshTime+1
end
end
function ifoverlap(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
if field[y+i-1]and bk[i][j]>0 and field[y+i-1][x+j-1]>0 then return true end
end end
end
function ckfull(i)
for j=1,10 do if field[i][j]==0 then return nil end end
return true
end
function checkrow(s,num)--(cy,r)
local c=0--rows cleared
for i=s,s+num-1 do if ckfull(i)then
ins(clearing,1,i)
P.falling=gameEnv.fall
c=c+1--row cleared+1
for k=1,250 do
PTC.dust[P.id]:setPosition(rnd(300),600-30*i+rnd(30))
PTC.dust[P.id]:emit(1)
end
end end
return c
end
function solid(x,y)
if x<1 or x>10 or y<1 then return true end
if y>#field then return false end
return field[y][x]>0
end
function resetblock()
P.holded=false
P.spinLast=false
P.freshNext()
P.sc,P.dir=scs[bn][0],0
P.r,P.c=#cb,#cb[1]
P.cx,P.cy=blockPos[bn],21+ceil(fieldBeneath/30)
P.dropDelay,P.lockDelay,P.freshTime=gameEnv.drop,gameEnv.lock,0
if keyPressing[8]then hold(true)end
if abs(moving)-gameEnv.das>1 then
if not ifoverlap(cb,cx+sgn(moving),cy)then
P.cx=cx+sgn(moving)
end
end
if keyPressing[3]then spin(1,true)end
if keyPressing[4]then spin(-1,true)end
if keyPressing[5]then spin(2,true)end
if ifoverlap(cb,cx,cy)then lock()Event.gameover.lose()end
freshgho()
if keyPressing[6]then act.hardDrop()P.keyPressing[6]=false end
end
function pressKey(i,player)
P=player or players[1]
setmetatable(_G,P.index)
P.keyPressing[i]=true
if i==9 then
act.restart()
elseif alive then
if control and waiting<=0 then
act[actName[i]]()
if i>2 and i<6 then keyPressing[i]=false end
elseif i==1 then
P.moving=-1
elseif i==2 then
P.moving=1
end
ins(keyTime,1,frame)rem(keyTime,11)
cstat.key=cstat.key+1
if player.id==1 then stat.key=stat.key+1 end
--Key count
end
-- if playmode=="recording"then ins(rec,{i,frame})end
end
function releaseKey(i,player)
P=player or players[1]
setmetatable(_G,P.index)
P.keyPressing[i]=false
-- if playmode=="recording"then ins(rec,{-i,frame})end
end
function spin(d,ifpre)
if bn==6 then
freshgho()--May cancel spinLast
freshLockDelay()
SFX(ifpre and"prerotate"or ifoverlap(cb,cx,cy+1)and ifoverlap(cb,cx-1,cy)and ifoverlap(cb,cx+1,cy)and"rotatekick"or"rotate")
if id==1 then
stat.rotate=stat.rotate+1
end
return nil
end
local icb=blocks[bn][(dir+d)%4]
local isc=d==1 and{c-sc[2]+1,sc[1]}or d==-1 and{sc[2],r-sc[1]+1}or{r-sc[1]+1,c-sc[2]+1}
local ir,ic=#icb,#icb[1]
local ix,iy=cx+sc[2]-isc[2],cy+sc[1]-isc[1]
local t--succssful num
local iki=TRS[bn][dir*10+(dir+d)%4]
for i=1,#iki do
if not ifoverlap(icb,ix+iki[i][1],iy+iki[i][2])then
ix,iy=ix+iki[i][1],iy+iki[i][2]
t=i
break
end
end
if t then
P.cx,P.cy=ix,iy
P.sc,P.cb=isc,icb
P.r,P.c=ir,ic
P.dir=(dir+d)%4
P.spinLast=t
freshgho()--May cancel spinLast
freshLockDelay()
SFX(ifpre and"prerotate"or ifoverlap(cb,cx,cy+1)and ifoverlap(cb,cx-1,cy)and ifoverlap(cb,cx+1,cy)and"rotatekick"or"rotate")
if id==1 then
stat.rotate=stat.rotate+1
end
end
end
function hold(ifpre)
if not holded and waiting<=0 and gameEnv.hold then
P.hn,P.bn=bn,hn
P.hb,P.cb=blocks[hn][0],hb
if bn==0 then freshNext()end
P.sc,P.dir=scs[bn][0],0
P.r,P.c=#cb,#cb[1]
P.cx,P.cy=blockPos[bn],21+ceil(fieldBeneath/30)
if abs(moving)-gameEnv.das>1 then
if not ifoverlap(cb,cx+sgn(moving),cy)then
P.cx=cx+sgn(moving)
end
end
freshgho()
P.dropDelay,P.lockDelay,P.freshTime=gameEnv.drop,gameEnv.lock,0
if ifoverlap(cb,cx,cy) then lock()Event.gameover.lose()end
P.holded=true
SFX(ifpre and"prehold"or"hold")
if id==1 then
stat.hold=stat.hold+1
end
end
end
function drop()
if cy==y_img then
ins(dropTime,1,frame)rem(dropTime,11)--update speed dial
P.waiting=gameEnv.wait
local dospin=bn~=6 and ifoverlap(cb,cx-1,cy)and ifoverlap(cb,cx+1,cy)and ifoverlap(cb,cx,cy+1)and 1 or 0
if bn<6 and spinLast then
local x,y=cx+sc[2]-1,cy+sc[1]-1
local c=0
if solid(x-1,y+1)then c=c+1 end
if solid(x+1,y+1)then c=c+1 end
if c>0 then
if solid(x-1,y-1)then c=c+1 end
if solid(x+1,y-1)then c=c+1 end
if c>2 then
dospin=dospin+(spinLast==2 and 1 or 2)
end
end
end--Three point
if dospin==0 then dospin=false end
lock()
local cc,csend,exblock,sendTime=checkrow(cy,r),0,0,0--Currect clear&send&sendTime
local mini=bn~=7 and dospin==1 and cc<3 and cc<r
P.combo=P.combo+1--combo=0 is under
if cc==4 then
if b2b>500 then
showText("Tetris B2B2B","fly",70)
csend=6
sendTime=80
exblock=exblock+1
elseif b2b>=100 then
showText("Tetris B2B","drive",70)
sendTime=70
csend=5
else
showText("Tetris","stretch",80)
sendTime=60
csend=4
end
P.b2b=P.b2b+100
P.cstat.tetris=P.cstat.tetris+1
elseif cc>0 then
if dospin then
if b2b>500 then
showText(spinName[cc][bn].." B2B2B","spin",40)
csend=b2bATK[cc]+1
exblock=exblock+1
elseif b2b>=100 then
showText(spinName[cc][bn].." B2B","spin",40)
csend=b2bATK[cc]
else
showText(spinName[cc][bn],"spin",50)
csend=2*cc
end
sendTime=20+csend*20
if mini then
showText("Mini","drive",40,10)
sendTime=sendTime+60
P.b2b=P.b2b+90+10*cc
else
P.b2b=P.b2b+70+30*cc
end
SFX(spin_n[cc])
if id==1 then
stat.spin=stat.spin+1
end
elseif #clearing<#field then
P.b2b=P.b2b-300
showText(clearName[cc],"appear",50)
csend=cc-1
sendTime=20+csend*20
end
else
P.combo=0
if dospin then
showText(spinName[0][bn],"appear",50)
SFX("spin_0")
P.b2b=b2b+30
end
end
if cc>0 and #clearing==#field then
showText("Perfect Clear","flicker",70,-80)
csend=csend+5
exblock=exblock+2
sendTime=sendTime+30
SFX("perfectclear")
if cstat.piece>10 then
P.b2b=600
end
end
csend=csend+(renATK[combo]or 4)
if combo>2 then
showText(renName[min(combo,20)],combo<10 and"appear"or"flicker",20+combo*3,60)
end
sendTime=sendTime+20*combo
if cc>0 then
SFX(clear_n[cc])
SFX(ren_n[min(combo,11)])
end
P.b2b=max(min(b2b,600),0)
if csend>0 then
if exblock then exblock=int(exblock*(1+P.strength*.25))end
csend=csend*(1+P.strength*.25)
if mini then csend=csend end
csend=int(csend)
--Buffs
P.cstat.atk=P.cstat.atk+csend
if P.id==1 then stat.atk=stat.atk+csend end
--ATK statistics
while csend>0 and P.atkBuffer[1]do
if exblock>0 then
exblock=exblock-1
else
csend=csend-1
end
P.atkBuffer[1].amount=P.atkBuffer[1].amount-1
if P.atkBuffer[1].amount==0 then
rem(P.atkBuffer,1)
end
if P.atkBuffer[1]and csend==0 then
local s=P.atkBuffer[1].amount
P.atkBuffer[1].lv=s<4 and 1 or s<7 and 2 or 3
end
end
if csend>0 then
showText(csend,"zoomout",25,70)
if #players.alive>1 then
garbageSend(P.id,csend,sendTime)
end
end
elseif cc==0 then
if P.b2b>450 then
P.b2b=max(b2b-2,450)
elseif P.b2b>100 then
P.b2b=max(b2b-5,100)
end
garbageRelease()
end
if id==1 then
stat.piece,stat.row=stat.piece+1,stat.row+cc
end
P.cstat.piece,P.cstat.row=P.cstat.piece+1,P.cstat.row+cc
if P.cstat.row>=gameEnv.target then
gameEnv.reach()
if control then SFX("reach")end
end
else
P.cy=cy-1
P.spinLast=false
end
end
function lock()
for i=1,r do
local y=cy+i-1
if not P.field[y]then P.field[y],P.visTime[y]=getNewRow(),getNewRow()end
for j=1,c do
if cb[i][j]~=0 then
P.field[y][cx+j-1]=P.bn
P.visTime[y][cx+j-1]=P.showTime
end
end
end
end
function garbageSend(sender,send,time)
local pos,r=rnd(10)
local level=send<4 and 1 or send<7 and 2 or 3
repeat
r=players.alive[rnd(#players.alive)]
until r~=P.id
createBeam(sender,r,level)
ins(players[r].atkBuffer,{pos,amount=send,countdown=time,cd0=time,time=0,sent=false,lv=level})
players[r].lastRecv=sender
sort(players[r].atkBuffer,timeSort)
end
function garbageRelease()
local t=P.showTime*2
for i=1,#P.atkBuffer do
local atk=P.atkBuffer[i]
if not atk.sent and atk.countdown==0 then
for j=1,atk.amount do
ins(P.field,1,getNewRow(13))
ins(P.visTime,1,getNewRow(t))
for k=1,#atk do
P.field[1][atk[k]]=0
end
end
atk.sent=true
atk.time=0
P.fieldBeneath=P.fieldBeneath+atk.amount*30
end
end
end

View File

Before

Width:  |  Height:  |  Size: 404 B

After

Width:  |  Height:  |  Size: 404 B

View File

Before

Width:  |  Height:  |  Size: 882 B

After

Width:  |  Height:  |  Size: 882 B

View File

Before

Width:  |  Height:  |  Size: 973 B

After

Width:  |  Height:  |  Size: 973 B

BIN
image/mess/badge.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 B

441
list.lua
View File

@@ -1,5 +1,3 @@
blockName={"Z","S","L","J","T","O","I"}
clearName={"Single","Double","Triple"}
color={
red={1,0,0},
green={0,1,0},
@@ -7,6 +5,7 @@ color={
yellow={1,1,0},
purple={1,0,1},
cyan={0,1,1},
grey={.6,.6,.6},
lightRed={1,.5,.5},
lightGreen={.5,1,.5},
@@ -14,9 +13,18 @@ color={
lightYellow={1,1,.5},
lightPurple={1,.5,1},
lightCyan={.5,1,1},
lightGrey={.8,.8,.8},
darkRed={.6,0,0},
darkGreen={0,.6,0},
darkBlue={0,0,.6},
darkYellow={.6,.6,0},
darkPurple={.6,0,.6},
darkCyan={0,.6,.6},
darkGrey={.3,.3,.3},
white={1,1,1},
grey={.6,.6,.6},
orange={1,.6,0},
}
attackColor={
{color.red,color.yellow},
@@ -34,37 +42,408 @@ attackColor={
end,
}--3 animation-colorsets of attack buffer bar
}
frameColor={
[0]=color.white,
color.green,
color.blue,
color.purple,
color.orange,
}
blockName={"Z","S","L","J","T","O","I"}
blockColor={
color.red,
color.green,
color.orange,
color.blue,
color.purple,
color.yellow,
color.cyan,
}
clearName={"Single","Double","Triple"}
spinName={[0]={}}
for i=1,3 do
spinName[i]={}
for j=1,7 do
spinName[i][j]=blockName[j].." spin "..clearName[i]
end
end
for j=1,7 do
spinName[0][j]=blockName[j].." spin"
end
actName={"moveLeft","moveRight","rotRight","rotLeft","rotFlip","hardDrop","softDrop","hold","restart","toLeft","toRight","toDown"}
actName_show={"move left","move right","rotate right","rotate left","rotate flip","hard drop","soft drop","hold","restart","toLeft","toRight","toDown"}
sfx={
"button",
"ready","start","win","fail",
"move","rotate","rotatekick","hold",
"prerotate","prehold",
"drop","fall",
"reach",
"ren_1","ren_2","ren_3","ren_4","ren_5","ren_6","ren_7","ren_8","ren_9","ren_10","ren_11",
"clear_1","clear_2","clear_3","clear_4",
"spin_0","spin_1","spin_2","spin_3",
"perfectclear",
}
bgm={
"blank",
"way",
"race",
"push",
"reason",
"infinite",
}
prevMenu={
load=love.event.quit,
ready="mode",
play="mode",
mode="main",
help="main",
stat="main",
setting=function()
saveSetting()
gotoScene("main")
end,
setting2="setting",
setting3="setting",
intro="quit",
main="quit",
}
modeID={"sprint","marathon","zen","infinite","solo","death","blind","puzzle","tetris41","asymsolo","gmroll","p2","p3","p4"}
modeName={"Sprint","Marathon","Zen","Infinite","1v1","Death","Blind","Puzzle","Tetris 41","Asymmetry solo","GM roll","2P","3P","4P"}
modeInfo={
sprint="Clear 40 Lines",
marathon="Clear 200 Lines",
zen="Clear 200 Lines without gravity",
infinite="Infinite game,infinite happiness",
solo="Beat AI",
death="Survive under terrible speed",
blind="Invisible board!",
puzzle="Your keyboard broke",
tetris41="Melee fight with 40 AIs",
asymsolo=" See-->",
gmroll="Who want to be the grand master?",
p2="2 players game",
p3="3 players game",
p4="4 players game",
}
actName={"moveLeft","moveRight","rotRight","rotLeft","rotFlip","hardDrop","softDrop","hold","restart","insLeft","insRight","insDown"}
actName_show={"Move Left:","Move Right:","Rotate Right:","Rotate Left:","Rotate Flip","Hard Drop:","Soft Drop:","Hold:","Restart:","Instant Left:","Instant Right:","Ins Down:"}
blockPos={4,4,4,4,4,5,4}
renATK={[0]=0,0,0,1,1,2,2,3,3,4,4}--3 else
renName={
[0]="","","",
"Combo 3",
"Combo 4",
"Combo 5",
"Combo 6",
"Combo 7",
"Combo 8",
"Combo 9",
"Combo 10 !",
"Combo 11 !",
"Combo 12 !",
"Combo 13 !",
"Combo 14 !",
"Combo 15 !",
"Combo 16 !",
"Combo 17 !",
"Combo 18 !",
"Combo 19 !",
"MEGACMB",
}
renName={nil,nil,"3 Combo","4 Combo","5 Combo","6 Combo","7 Combo","8 Combo","9 Combo","10 Combo!","11 Combo!","12 Combo!","13 Combo!","14 Combo!","15 Combo!","16 Combo!","17 Combo!","18 Combo!","19 Combo!","MEGACMB",}
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}
spin_n={"spin_1","spin_2","spin_3"}
clear_n={"clear_1","clear_2","clear_3","clear_4"}
ren_n={"ren_1","ren_2","ren_3","ren_4","ren_5","ren_6","ren_7","ren_8","ren_9","ren_10","ren_11"}
percent0to5={[0]="0%","20%","40%","60%","80%","100%",}
percent0to5={[0]="0%","20%","40%","60%","80%","100%",}
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,9,8,8}
death_wait={6,6,5,5,4}
death_fall={10,9,8,7,6}
snapLevelValue={1,10,20,40,60,80}
snapLevelName={"Free pos","Snap-10","Snap-20","Snap-40","Snap-60","Snap-80"}
act={
moveLeft=function(auto)
if not auto then P.moving=-1 end
if not ifoverlap(cb,cx-1,cy)then
P.cx=cx-1
freshgho()
freshLockDelay()
if cy==y_img then SFX("move")end
P.spinLast=false
end
end,
moveRight=function(auto)
if not auto then P.moving=1 end
if not ifoverlap(cb,cx+1,cy)then
P.cx=cx+1
freshgho()
freshLockDelay()
if cy==y_img then SFX("move")end
P.spinLast=false
end
end,
hardDrop=function()
if P.waiting<=0 then
if cy~=y_img then
P.cy=y_img
P.spinLast=false
SFX("drop")
end
drop()
P.keyPressing[6]=false
end
end,
softDrop=function()
if cy~=y_img then P.cy=cy-1 end
P.downing=1
end,
rotRight=function()spin(1)end,
rotLeft=function()spin(-1)end,
rotFlip=function()spin(2)end,
hold=function()hold()end,
--Player movements
restart=function()
resetGameData()
count=60+26--Althour'z neim
end,
insDown=function()if cy~= y_img then P.cy,P.lockDelay,P.spinLast=y_img,gameEnv.lock,false end end,
insLeft=function()
while not ifoverlap(cb,cx-1,cy)do
P.cx,P.lockDelay=cx-1,gameEnv.lock
freshgho()
end
end,
insRight=function()
while not ifoverlap(cb,cx+1,cy)do
P.cx,P.lockDelay=cx+1,gameEnv.lock
freshgho()
end
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 P.cy=cy-1 else break end end end,
quit=function()Event.gameover.lose()end,
--System movements
}
blocks={
{[0]={{0,1,1},{1,1,0}},{{1,0},{1,1},{0,1}},{{0,1,1},{1,1,0}},{{1,0},{1,1},{0,1}}},
{[0]={{1,1,0},{0,1,1}},{{0,1},{1,1},{1,0}},{{1,1,0},{0,1,1}},{{0,1},{1,1},{1,0}}},
{[0]={{1,1,1},{0,0,1}},{{1,1},{1,0},{1,0}},{{1,0,0},{1,1,1}},{{0,1},{0,1},{1,1}}},
{[0]={{1,1,1},{1,0,0}},{{1,0},{1,0},{1,1}},{{0,0,1},{1,1,1}},{{1,1},{0,1},{0,1}}},
{[0]={{1,1,1},{0,1,0}},{{1,0},{1,1},{1,0}},{{0,1,0},{1,1,1}},{{0,1},{1,1},{0,1}}},
{[0]={{1,1},{1,1}},{{1,1},{1,1}},{{1,1},{1,1}},{{1,1},{1,1}}},
{[0]={{1,1,1,1}},{{1},{1},{1},{1}},{{1,1,1,1}},{{1},{1},{1},{1}}},
}
scs={
{[0]={1,2},{2,1},{2,2},{2,2}},
{[0]={1,2},{2,1},{2,2},{2,2}},
{[0]={1,2},{2,1},{2,2},{2,2}},
{[0]={1,2},{2,1},{2,2},{2,2}},
{[0]={1,2},{2,1},{2,2},{2,2}},
{[0]={1.5,1.5},{1.5,1.5},{1.5,1.5},{1.5,1.5},},
{[0]={0.5,2.5},{2.5,0.5},{1.5,2.5},{2.5,1.5}},
}
TRS={
[1]={
[01]={{0,0},{-1,0},{-1,1},{0,-2},{-1,-2},{0,1}},
[10]={{0,0},{1,0},{1,-1},{0,2},{1,2},{0,-1}},
[12]={{0,0},{1,0},{1,-1},{0,2},{1,2}},
[21]={{0,0},{-1,0},{-1,1},{0,-2},{-1,-2}},
[23]={{0,0},{1,0},{1,1},{0,-2},{1,-2}},
[32]={{0,0},{-1,0},{-1,-1},{0,2},{-1,2}},
[30]={{0,0},{-1,0},{-1,-1},{0,2},{-1,2}},
[03]={{0,0},{1,0},{1,1},{0,-2},{1,-2}},
[02]={{0,0},{1,0},{-1,0},{0,-1},{0,1}},
[20]={{0,0},{-1,0},{1,0},{0,1},{0,-1}},
[13]={{0,0},{0,-1},{0,1},{-1,0},{1,0},{0,2}},
[31]={{0,0},{0,1},{0,-1},{1,0},{-1,0},{0,2}},
},
[2]={
[01]={{0,0},{-1,0},{-1,1},{0,-2},{-1,-2}},
[10]={{0,0},{1,0},{1,-1},{0,2},{1,2}},
[12]={{0,0},{1,0},{1,-1},{0,2},{1,2}},
[21]={{0,0},{-1,0},{-1,1},{0,-2},{-1,-2}},
[23]={{0,0},{1,0},{1,1},{0,-2},{1,-2}},
[32]={{0,0},{-1,0},{-1,-1},{0,2},{-1,2}},
[30]={{0,0},{-1,0},{-1,-1},{0,2},{-1,2},{0,-1}},
[03]={{0,0},{1,0},{1,1},{0,-2},{1,-2},{0,1}},
[02]={{0,0},{-1,0},{1,0},{0,-1},{0,1}},
[20]={{0,0},{1,0},{-1,0},{0,1},{0,-1}},
[13]={{0,0},{0,1},{0,-1},{1,0},{-1,0},{0,2}},
[31]={{0,0},{0,-1},{0,1},{-1,0},{1,0},{0,2}},
},
[5]={
[01]={{0,0},{-1,0},{-1,1},{0,-2},{-1,-2}},
[10]={{0,0},{1,0},{1,-1},{0,2},{1,2},{0,-1}},
[12]={{0,0},{1,0},{1,-1},{0,2},{1,2}},
[21]={{0,0},{-1,0},{-1,1},{0,-2},{-1,-2}},
[23]={{0,0},{1,0},{1,1},{0,-2},{1,-2}},
[32]={{0,0},{-1,0},{-1,-1},{0,2},{-1,2}},
[30]={{0,0},{-1,0},{-1,-1},{0,2},{-1,2},{0,-1}},
[03]={{0,0},{1,0},{1,1},{0,-2},{1,-2},{0,1}},
[02]={{0,0},{-1,0},{1,0},{0,-1},{0,1}},
[20]={{0,0},{1,0},{-1,0},{0,1},{0,-1}},
[13]={{0,0},{0,-1},{0,1},{1,0},{-1,0},{0,2}},
[31]={{0,0},{0,-1},{0,1},{-1,0},{1,0},{0,2}},
},
[7]={
[01]={{0,0},{1,0},{-2,0},{-2,-1},{1,2}},
[10]={{0,0},{2,0},{-1,0},{2,1},{-1,-2}},
[12]={{0,0},{-1,0},{2,0},{-1,2},{2,-1}},
[21]={{0,0},{-2,0},{1,0},{1,-2},{-2,1}},
[23]={{0,0},{2,0},{-1,0},{-1,-2},{2,1}},
[32]={{0,0},{-2,0},{1,0},{-2,-1},{1,2}},
[30]={{0,0},{1,0},{-2,0},{1,-2},{-2,1}},
[03]={{0,0},{-1,0},{2,0},{2,-1},{-1,2}},
[02]={{0,0},{-1,0},{1,0},{0,-1},{0,1}},
[20]={{0,0},{1,0},{-1,0},{0,1},{0,-1}},
[13]={{0,0},{0,-1},{-1,0},{1,0},{0,1}},
[31]={{0,0},{0,-1},{1,0},{-1,0},{0,1}},
}
}TRS[3],TRS[4]=TRS[2],TRS[1]
Buttons={
load={},
intro={},
main={
{x=250,y=300,w=330,h=60,rgb=color.red,t="Play",code=function()gotoScene("mode")end,down=2},
{x=250,y=380,w=330,h=60,rgb=color.blue,t="Settings",code=function()gotoScene("setting")end,up=1,down=3},
{x=165,y=460,w=160,h=60,rgb=color.yellow,t="Help",code=function()gotoScene("help")end,up=2,down=5,right=4},
{x=335,y=460,w=160,h=60,rgb=color.cyan,t="Statistics",code=function()gotoScene("stat")end,up=2,down=5,left=3},
{x=250,y=540,w=330,h=60,rgb=color.grey,t="Quit",code=function()gotoScene("quit")end,up=3},
},
mode={
{x=1000,y=210,w=200,h=140,rgb=color.white,hide=function()return not setting.virtualkeySwitch end,code=function()if modeSel>1 then modeSel=modeSel-1 end end},
{x=1000,y=430,w=200,h=140,rgb=color.white,t="v",f=80,hide=function()return not setting.virtualkeySwitch end,code=function()if modeSel<#modeID then modeSel=modeSel+1 end end},
{x=1000,y=600,w=180,h=80,rgb=color.green,t="Start",code=function()startGame(modeID[modeSel])end},
{x=640,y=630,w=180,h=60,rgb=color.white,t="Back",code=function()gotoScene("main")end},
},
play={
},
setting={--Normal setting
{x=330,y=100,w=200,h=60,rgb=color.white,t=function()return setting.ghost and"Ghost ON"or"Ghost OFF"end,code=function()setting.ghost=not setting.ghost end,down=3,right=2},
{x=540,y=100,w=200,h=60,rgb=color.white,t=function()return setting.center and"Center ON"or"Center OFF"end,code=function()setting.center=not setting.center end,down=5,left=1,right=11},
--1,2
{x=245,y=180,w=40,h=40,rgb=color.white,t="-",code=function()setting.das=(setting.das-1)%31 end,up=1,down=7,right=4},
{x=410,y=180,w=40,h=40,rgb=color.white,t="+",code=function()setting.das=(setting.das+1)%31 end,up=1,down=8,left=3,right=5},
{x=460,y=180,w=40,h=40,rgb=color.white,t="-",code=function()setting.arr=(setting.arr-1)%16 end,up=2,down=9,left=4,right=6},
{x=625,y=180,w=40,h=40,rgb=color.white,t="+",code=function()setting.arr=(setting.arr+1)%16 end,up=2,down=10,left=5,right=13},
--3~6
{x=245,y=260,w=40,h=40,rgb=color.white,t="-",code=function()setting.sddas=(setting.sddas-1)%11 end,up=3,down=17,right=8},
{x=410,y=260,w=40,h=40,rgb=color.white,t="+",code=function()setting.sddas=(setting.sddas+1)%11 end,up=4,down=17,left=7,right=9},
{x=460,y=260,w=40,h=40,rgb=color.white,t="-",code=function()setting.sdarr=(setting.sdarr-1)%6 end,up=5,down=17,left=8,right=10},
{x=625,y=260,w=40,h=40,rgb=color.white,t="+",code=function()setting.sdarr=(setting.sdarr+1)%4 end,up=6,down=17,left=9,right=14},
--7~10
{x=870-90,y=100,w=160,h=60,rgb=color.white,t=function()return setting.sfx and"SFX:on"or"SFX:off"end,code=function()setting.sfx=not setting.sfx end,down=13,left=2,right=12},
{x=870+90,y=100,w=160,h=60,rgb=color.white,t=function()return setting.bgm and"BGM:on"or"BGM:off"end,code=function()BGM()setting.bgm=not setting.bgm;BGM("blank")end,down=13,left=11},
{x=870,y=180,w=340,h=60,rgb=color.white,t=function()return setting.fullscreen and"Fullscreen:on"or"Fullscreen:off"end,
code=function()
setting.fullscreen=not setting.fullscreen
love.window.setFullscreen(setting.fullscreen)
if not setting.fullscreen then
love.resize(gc.getWidth(),gc.getHeight())
end
end,
up=11,down=14,left=6
},
{x=870,y=260,w=340,h=60,rgb=color.white,t=function()return setting.bgblock and"BG animation:on"or"BG animation:off"end,
code=function()
setting.bgblock=not setting.bgblock
if not setting.bgblock then
for i=1,16 do
BGblockList[i].v=3*BGblockList[i].v
end
end
end,
up=12,down=15,left=10
},
--11~14
{x=870,y=340,w=340,h=60,rgb=color.white,t=function()return"frameDraw:"..setting.frameMul.."%"end,code=function()
setting.frameMul=setting.frameMul+(setting.frameMul<50 and 5 or 10)
if setting.frameMul>100 then setting.frameMul=25 end
end,up=14,down=16},
{x=870,y=420,w=340,h=60,rgb=color.green,t="Control settings",code=function()gotoScene("setting2")end,up=15,down=17},
{x=870,y=500,w=340,h=60,rgb=color.yellow,t="Touch settings",code=function()gotoScene("setting3")end,up=16,down=18},
{x=640,y=640,w=210,h=60,rgb=color.white,t="Save&Back",code=function()back()end,up=17},
--15~18
},
setting2={--Control setting
{x=840,y=630,w=180,h=60,rgb=color.white,t="Back",code=function()keysetting=nil;back()end},
},
setting3={--Touch setting
{x=640,y=410,w=170,h=80,t="Back",code=function()back()end},
{x=640,y=210,w=500,h=80,t=function()return setting.virtualkeySwitch and"Hide Virtual Key"or"Show Virtual Key"end,code=function()
setting.virtualkeySwitch=not setting.virtualkeySwitch
end},
{x=450,y=310,w=170,h=80,t="Reset",code=function()
for K=1,#virtualkey do
local b,b0=virtualkey[K],gameEnv0.virtualkey[K]
b[1],b[2],b[3],b[4]=b0[1],b0[2],b0[3],b0[4]
end--Reset virtualkey
end},
{x=640,y=310,w=170,h=80,t=function()return snapLevelName[snapLevel]end,code=function()
snapLevel=snapLevel%6+1
end},
{x=830,y=310,w=170,h=80,t=function()return percent0to5[setting.virtualkeyAlpha]end,code=function()
setting.virtualkeyAlpha=(setting.virtualkeyAlpha+1)%6
--Adjust virtualkey alpha
end},
{x=450,y=410,w=170,h=80,t="Icon",code=function()
setting.virtualkeyIcon=not setting.virtualkeyIcon
--Switch virtualkey icon
end},
{x=830,y=410,w=170,h=80,t="Size",code=function()
if sel then
local b=virtualkey[sel]
b[4]=b[4]+10
if b[4]==150 then b[4]=40 end
b[3]=b[4]^2
end
end},
},
help={
{x=640,y=590,w=180,h=60,rgb=color.white,t="Back",code=function()back()end,right=2},
{x=980,y=590,w=230,h=60,rgb=color.white,t="Author's qq",code=function()sys.openURL("tencent://message/?uin=1046101471&Site=&Menu=yes")end,left=1},
},
stat={
{x=640,y=590,w=180,h=60,rgb=color.white,t="Back",code=function()back()end},
},
sel=nil,--selected button id(integer)
}
for k,v in pairs(Buttons)do
for i=1,#v do
v[i].alpha=0
end
end
virtualkey={
{80,720-80,6400,80},--moveLeft
{240,720-80,6400,80},--moveRight
{1280-240,720-80,6400,80},--rotRight
{1280-400,720-80,6400,80},--rotLeft
{1280-240,720-240,6400,80},--rotFlip
{1280-80,720-80,6400,80},--hardDrop
{1280-80,720-240,6400,80},--softDrop
{1280-80,720-400,6400,80},--hold
{80,80,6400,80},--restart
--[[
{x=0,y=0,r=0},--toLeft
{x=0,y=0,r=0},--toRight
{x=0,y=0,r=0},--toDown
]]
}
Text={
load={"Loading textures","Loading BGM","Loading SFX","Finished",},
stat={
"Games run:",
"Games played:",
"Game time:",
"Total block used:",
"Total rows cleared:",
"Total lines sent:",
"Total key pressed:",
"Total rotate:",
"Total hold:",
"Total spin:",
},
help={
"I think you don't need \"help\".",
"THIS IS NOT TETRIS,and SRS NOT USED.",
"But just play like playing TOP/C2/KOS/TGM3",
"Game is not public now,so DO NOT DISTIRBUTE",
"",
"Powered by LOVE2D",
"Author:MrZ E-mail:1046101471@qq.com",
"Programe:MrZ Art:MrZ Music:MrZ SFX:MrZ",
"Tool used:VScode,GFIE,Beepbox,Goldwave",
"Special thanks:farter,teatube,flyz,and YOU!!",
"Any bugs/suggestions to my E-mail.",
},
}

1141
main.lua

File diff suppressed because it is too large Load Diff

335
paint.lua
View File

@@ -32,6 +32,66 @@ swap={
end
},
}--Scene swapping animations
FX={
flash=0,--Black screen(frame)
shake=0,--Screen shake(frame)
beam={},--Attack beam
badge={},--badge thrown
appear=function(t,a)
setFont(t.font)
gc.setColor(1,1,1,a)
mStr(t.text,150,250-t.font*.5+t.dy)
end,
fly=function(t,a)
setFont(t.font)
gc.setColor(1,1,1,a)
mStr(t.text,150+(t.t-15)^3*.005,250-t.font*.5+t.dy)
end,
stretch=function(t,a)
gc.push("transform")
setFont(t.font)
gc.translate(150,250+t.dy)
gc.setColor(1,1,1,a)
if t.t<20 then gc.scale((20-t.t)*.015+1,1)end
mStr(t.text,0,-t.font*.5)
gc.pop()
end,
drive=function(t,a)
gc.push("transform")
setFont(t.font)
gc.translate(150,290+t.dy)
gc.setColor(1,1,1,a)
if t.t<20 then gc.shear((20-t.t)*.05,0)end
mStr(t.text,0,-t.font*.5)
gc.pop()
end,
spin=function(t,a)
gc.push("transform")
setFont(t.font)
gc.translate(150,250+t.dy)
gc.setColor(1,1,1,a)
if t.t<20 then
gc.rotate((20-t.t)^2*.0015)
end
mStr(t.text,0,-t.font*.5)
gc.pop()
end,
flicker=function(t,a)
setFont(t.font)
gc.setColor(1,1,1,a*(rnd()+.5))
mStr(t.text,150,250-t.font*.5+t.dy)
end,
zoomout=function(t,a)
gc.push("transform")
setFont(t.font)
gc.translate(150,290+t.dy)
gc.setColor(1,1,1,a)
local k=t.t^.5*.2+1
gc.scale(k,k)
mStr(t.text,0,-t.font*.5)
gc.pop()
end
}
function drawButton()
for i=1,#Buttons[scene]do
@@ -40,21 +100,27 @@ function drawButton()
local t=i==Buttons.sel and .3 or 0
B.alpha=abs(B.alpha-t)>.02 and(B.alpha+(B.alpha<t and .02 or -.02))or t
if B.alpha>t then B.alpha=B.alpha-.02 elseif B.alpha<t then B.alpha=B.alpha+.02 end
gc.setColor(B.rgb[1],B.rgb[2],B.rgb[3],B.alpha)
local C=B.rgb or color.white
gc.setColor(C[1],C[2],C[3],B.alpha)
gc.rectangle("fill",B.x-B.w*.5,B.y-B.h*.5,B.w,B.h)
local t=B.t
if type(t)=="function"then t=t()end
gc.setColor(B.rgb[1],B.rgb[2],B.rgb[3],.3)
gc.setColor(C[1],C[2],C[3],.3)
gc.setLineWidth(5)gc.rectangle("line",B.x-B.w*.5,B.y-B.h*.5,B.w,B.h)
local y0=B.y-1-currentFont*.5
mStr(t,B.x-1,y0)
mStr(t,B.x+1,y0)
mStr(t,B.x-1,y0+2)
mStr(t,B.x+1,y0+2)
gc.setColor(B.rgb)
local t=B.t
local y0
if t then
if type(t)=="function"then t=t()end
setFont(B.f or 40)
y0=B.y-1-currentFont*.5
mStr(t,B.x-1,y0)
mStr(t,B.x+1,y0)
mStr(t,B.x-1,y0+2)
mStr(t,B.x+1,y0+2)
end
gc.setColor(C)
if t then
mStr(t,B.x,y0+1)
end
gc.setLineWidth(3)gc.rectangle("line",B.x-B.w*.5,B.y-B.h*.5,B.w,B.h)
mStr(t,B.x,B.y-currentFont*.5)
end
end
end
@@ -72,13 +138,22 @@ function drawPixel(y,x,id,alpha)
gc.setColor(1,1,1,alpha)
gc.draw(blockSkin[id],30*x-30,600-30*y)
end
function drawVirtualkey()
function drawVirtualkey(s)
gc.setLineWidth(10)
gc.setColor(1,1,1,setting.virtualkeyAlpha*.2)
for i=1,#virtualkey do
local b=virtualkey[i]
gc.circle("line",b[1],b[2],b[4]-5)
if setting.virtualkeyIcon then gc.draw(virtualkeyIcon[i],b[1],b[2],nil,2*b[4]*.0125,nil,18,18)end
if s then
for i=1,#virtualkey do
gc.setColor(1,s==i and 0 or 1,s==i and 0 or 1,setting.virtualkeyAlpha*.2)
local b=virtualkey[i]
gc.circle("line",b[1],b[2],b[4]-5)
if setting.virtualkeyIcon then gc.draw(virtualkeyIcon[i],b[1],b[2],nil,2*b[4]*.0125,nil,18,18)end
end
else
gc.setColor(1,1,1,setting.virtualkeyAlpha*.2)
for i=1,#virtualkey do
local b=virtualkey[i]
gc.circle("line",b[1],b[2],b[4]-5)
if setting.virtualkeyIcon then gc.draw(virtualkeyIcon[i],b[1],b[2],nil,2*b[4]*.0125,nil,18,18)end
end
end
end
@@ -130,12 +205,35 @@ end
function Pnt.main()
gc.setColor(1,1,1)
setFont(30)
gc.print("Alpha V0.4",370,150)
if system==2 then
gc.print("Android",530,110)
end
gc.print("Alpha V0.68",370,150)
gc.print(system,530,110)
gc.draw(titleImage,30,30)
end
function Pnt.mode()
if setting.virtualkeySwitch then
gc.setColor(.5,.5,.5)
gc.draw(charV,1019,249,pi)
gc.draw(charV,1021,249,pi)
gc.draw(charV,1019,251,pi)
gc.draw(charV,1020,251,pi)
gc.setColor(1,1,1)
gc.draw(charV,1020,250,pi)
end
gc.setColor(1,1,1)
setFont(30)
mStr(modeInfo[modeID[modeSel]],270,300)
setFont(80)
gc.setColor(color.grey)
mStr(modeName[modeSel],643,283)
for i=modeSel-2,modeSel+2 do
if i>=1 and i<=#modeID then
local f=80-abs(i-modeSel)*20
gc.setColor(i==modeSel and color.white or abs(i-modeSel)==1 and color.grey or color.darkGrey)
setFont(f)
mStr(modeName[i],640,320+70*(i-modeSel)-f*.5)
end
end
end
function Pnt.play()
for p=1,#players do
P=players[p]
@@ -144,9 +242,8 @@ function Pnt.play()
gc.push("transform")
gc.translate(x,y)gc.scale(size)--Scale
gc.setColor(0,0,0,.5)gc.rectangle("fill",0,0,300,600)--Black Background
gc.setLineWidth(3)
gc.translate(10,15)
gc.stencil(stencil_field, "replace", 1)
gc.setLineWidth(13)
gc.stencil(stencil_field_small, "replace",1)
gc.translate(0,fieldBeneath)
gc.setStencilTest("equal",1)
for j=1,#field do
@@ -156,77 +253,51 @@ function Pnt.play()
drawPixel(j,i,field[j][i],min(visTime[j][i],20)*.05)
end
end
else
gc.setColor(1,1,1,falling/gameEnv.fall)
gc.rectangle("fill",0,600-30*j,320,30)
end
end--Field
if gameEnv.ghost then
for i=1,r do for j=1,c do
if cb[i][j]>0 then
drawPixel(i+y_img-1,j+cx-1,bn,.3)
end
end end
end--Ghost
if waiting<=0 then
gc.setColor(2,2,2)
for i=1,r do for j=1,c do
if cb[i][j]>0 then
drawPixel(i+cy-1,j+cx-1,bn,1)
end
end end--Block
end
gc.setColor(1,1,1)
gc.draw(PTC.dust[p])--Draw game field
gc.setStencilTest()--In-playField mask
gc.translate(0,-fieldBeneath)
gc.setColor(1,1,1)gc.rectangle("line",-2,-12,304,614)--Draw boarder
gc.setColor(frameColor[P.strength])gc.rectangle("line",-7,-7,314,614)--Draw boarder
local h=0
for i=1,#atkBuffer do
local a=atkBuffer[i]
local bar=a.amount*30
if not a.sent then
if a.time<20 then
bar=bar*(20*a.time)^.5*.05
--Appear
if P.result then
gc.setColor(1,1,1,min(P.counter,60)*.01)
setFont(100)
mStr(P.result,150,250)
else
local h=0
for i=1,#atkBuffer do
local a=atkBuffer[i]
local bar=a.amount*30
if not a.sent then
if a.countdown>0 then
gc.setColor(attackColor[a.lv][1])
gc.rectangle("fill",315,600-h,8,-bar+5)
gc.setColor(attackColor[a.lv][2])
gc.rectangle("fill",315,600-h+(-bar+5),8,-(-bar+5)*(1-a.countdown/a.cd0))
--Timing
else
attackColor.animate[a.lv]((sin((Timer()-i)*20)+1)*.5)
gc.rectangle("fill",315,600-h,8,-bar+5)
--Warning
end
end
if a.countdown>0 then
gc.setColor(attackColor[a.lv][1])
gc.rectangle("fill",305,600-h,8,-bar+5)
gc.setColor(attackColor[a.lv][2])
gc.rectangle("fill",305,600-h+(-bar+5),8,-(-bar+5)*(1-a.countdown/a.cd0))
--Timing
else
attackColor.animate[a.lv]((sin((Timer()-i)*20)+1)*.5)
gc.rectangle("fill",305,600-h,8,-bar+5)
--Warning
end
else
gc.setColor(attackColor[a.lv][1])
bar=bar*(20-a.time)*.05
gc.rectangle("fill",305,600-h,8,-bar+5)
--Disappear
end
h=h+bar
if h>600 then break end
end--Buffer line
h=h+bar
if h>600 then break end
end--Buffer line
gc.setColor(b2b<100 and color.white or b2b<=480 and color.lightRed or color.lightBlue)
gc.rectangle("fill",-15,600,10,-b2b1)
--B2B bar
for i=1,#bonus do
local a=#field>9-bonus[i].dy*.03333 and .6 or 1
bonus[i]:draw(a)
end--Effects
gc.setColor(b2b<100 and color.white or b2b<=480 and color.lightRed or color.lightBlue)
gc.rectangle("fill",-15,600,10,-b2b)
--B2B bar
end
gc.pop()
else
gc.push("transform")
gc.translate(x,y)gc.scale(size)--Scale
gc.setColor(0,0,0,.7)gc.rectangle("fill",0,0,600,690)--Black Background
gc.setLineWidth(3)
gc.setColor(1,1,1)gc.rectangle("line",0,0,600,690)--Big frame
gc.setLineWidth(7)
gc.setColor(frameColor[P.strength])gc.rectangle("line",0,0,600,690)--Big frame
gc.translate(150,70)
gc.stencil(stencil_field, "replace", 1)
gc.translate(0,fieldBeneath)
@@ -273,7 +344,7 @@ function Pnt.play()
gc.draw(PTC.dust[p])--Draw game field
gc.setStencilTest()--In-playField mask
gc.translate(0,-fieldBeneath)
gc.setColor(1,1,1)gc.rectangle("line",-2,-12,304,614)--Draw boarder
gc.setColor(1,1,1)gc.rectangle("line",-3,-13,306,616)--Draw boarder
local h=0
for i=1,#atkBuffer do
@@ -286,36 +357,36 @@ function Pnt.play()
end
if a.countdown>0 then
gc.setColor(attackColor[a.lv][1])
gc.rectangle("fill",305,600-h,8,-bar+5)
gc.rectangle("fill",308,600-h,8,-bar+5)
gc.setColor(attackColor[a.lv][2])
gc.rectangle("fill",305,600-h+(-bar+5),8,-(-bar+5)*(1-a.countdown/a.cd0))
gc.rectangle("fill",308,600-h+(-bar+5),8,-(-bar+5)*(1-a.countdown/a.cd0))
--Timing
else
attackColor.animate[a.lv]((sin((Timer()-i)*20)+1)*.5)
gc.rectangle("fill",305,600-h,8,-bar+5)
gc.rectangle("fill",308,600-h,8,-bar+5)
--Warning
end
else
gc.setColor(attackColor[a.lv][1])
bar=bar*(20-a.time)*.05
gc.rectangle("fill",305,600-h,8,-bar+5)
gc.rectangle("fill",308,600-h,8,-bar+5)
--Disappear
end
h=h+bar
if h>600 then break end
end--Buffer line
gc.setColor(b2b<100 and color.white or b2b<=480 and color.lightRed or color.lightBlue)
gc.rectangle("fill",-15,600,10,-b2b1)
gc.setColor(b2b<100 and color.white or b2b<=500 and color.lightRed or color.lightBlue)
gc.rectangle("fill",-17,600,10,-b2b1)
gc.setColor(color.red)
gc.rectangle("line",-20,600-100,15,2)
gc.rectangle("fill",-23,600-100,16,5)
gc.setColor(color.blue)
gc.rectangle("line",-20,600-480,15,2)
gc.rectangle("fill",-23,600-500,16,5)
--B2B bar
setFont(40)
gc.setColor(1,1,1)
if gameEnv.hold then
gc.setColor(1,1,1)
gc.print("Hold",-113,0)
for i=1,#hb do
for j=1,#hb[1] do
@@ -325,9 +396,8 @@ function Pnt.play()
end
end
end--Hold
gc.print("Next",336,0)
for N=1,gameEnv.next do
gc.setColor(1,1,1)
gc.print("Next",336,0)
local b=nb[N]
for i=1,#b do
for j=1,#b[1] do
@@ -347,13 +417,12 @@ function Pnt.play()
gc.pop()
end--Draw starting counter
for i=1,#bonus do
local a=#field>(9-bonus[i].dy*.03333)and .7 or 1
bonus[i]:draw(a)
bonus[i]:draw(min((30-abs(bonus[i].t-30))*.05,1)*(not bonus[i].solid and #field>(9-bonus[i].dy*.03333)and .7 or 1))
end--Effects
gc.setColor(1,1,1)
setFont(40)
gc.print(format("%0.2f",time),-125,530)--Draw time
gc.print(format("%.2f",time),-130,530)--Draw time
if mesDisp[gamemode]then mesDisp[gamemode]()end--Draw other message
setFont(15)
@@ -371,36 +440,70 @@ function Pnt.play()
for i=1,3 do
gc.draw(PTC.attack[i])
end
for i=1,#FX.badge do
local b=FX.badge[i]
local t=b.t<10 and 0 or b.t<50 and(sin(1.5*(b.t/20-1.5))+1)*.5 or 1
gc.setColor(1,1,1,b.t<10 and b.t*.1 or b.t<50 and 1 or(60-b.t)*.1)
gc.draw(badgeIcon,b[1]+(b[3]-b[1])*t,b[2]+(b[4]-b[2])*t,nil,b.size,nil,14,14)
end
setmetatable(_G,nil)
if setting.virtualkeySwitch then
drawVirtualkey()
end
end
function Pnt.setting2()
function Pnt.setting()
gc.setColor(1,1,1)
setFont(18)
mStr("softdropDAS:"..setting.sddas,828,140)
mStr("softdropARR:"..setting.sdarr,1043,140)
setFont(35)
mStr("DAS:"..setting.das,828,73)
mStr("ARR:"..setting.arr,1043,73)
gc.print("Keyboard Joystick",223,10)
for i=1,9 do
gc.printf(actName_show[i]..":",0,60*i-8,180,"right")
mStr("DAS:"..setting.das,328,163)
mStr("ARR:"..setting.arr,543,163)
setFont(18)
mStr("softdropDAS:"..setting.sddas,328,250)
mStr("softdropARR:"..setting.sdarr,543,250)
end
function Pnt.setting2()
if keyboardSetting then
gc.setColor(1,.5,.5,.2+(sin(Timer()*15)+1)*.1)
else
gc.setColor(.9,.9,.9,.2+(sin(Timer()*15)+1)*.1)
end
if keysetting or gamepadsetting then
gc.print("<<",keysetting and 380 or 670,60*(keysetting or gamepadsetting)-10)
gc.rectangle("fill",240,40*keyboardSet-10,200,40)
if joystickSetting then
gc.setColor(1,.5,.5,.2+(sin(Timer()*15)+1)*.1)
else
gc.setColor(.9,.9,.9,.2+(sin(Timer()*15)+1)*.1)
end
gc.rectangle("fill",440,40*joystickSet-10,200,40)
gc.setColor(1,1,1)
setFont(40)
gc.print("< P"..curBoard.."/P8 >",430,530)
setFont(25)
for y=1,12 do
mStr(actName_show[y],150,40*y)
for x=1,2 do
mStr(setting.keyMap[curBoard+x*8-8][y],200*x+140,40*y)
end
gc.line(40,40*y-10,640,40*y-10)
end
for x=1,4 do
gc.line(200*x-160,30,200*x-160,510)
end
gc.line(40,510,640,510)
gc.print("Keyboard | Joystick",330,3)
gc.print("Arrowkey to select/change slot,Enter to change,Esc back",50,580)
end
function Pnt.setting3()
drawVirtualkey()
gc.setLineWidth(3)
gc.setColor(1,1,1,sin(Timer()*4)*.1+.1)
for i=1,31 do
gc.line(40*i,0,40*i,720)
end
for i=1,17 do
gc.line(0,40*i,1280,40*i)
drawVirtualkey(sel)
local d=snapLevelValue[snapLevel]
if d>=10 then
gc.setLineWidth(3)
gc.setColor(1,1,1,sin(Timer()*4)*.1+.1)
for i=1,1280/d-1 do
gc.line(d*i,0,d*i,720)
end
for i=1,720/d-1 do
gc.line(0,d*i,1280,d*i)
end
end
end
function Pnt.help()

View File

@@ -1,33 +0,0 @@
PTC={dust={}}--Particle systems
c=gc.newCanvas(6,6)gc.setCanvas(c)
gc.clear(1,1,1)
PTC.dust[0]=gc.newParticleSystem(c,1000)
PTC.dust[0]:setParticleLifetime(.2,.3)
PTC.dust[0]:setEmissionRate(0)
PTC.dust[0]:setLinearAcceleration(-1500,-200,1500,200)
PTC.dust[0]:setColors(1,1,1,.5,1,1,1,0)
c:release()
--Dust particles
PTC.attack={}
PTC.attack[1]=gc.newParticleSystem(gc.newImage("/image/attack/1.png"),200)
PTC.attack[1]:setParticleLifetime(.25)
PTC.attack[1]:setEmissionRate(0)
PTC.attack[1]:setSpin(10)
PTC.attack[1]:setColors(1,1,1,.7,1,1,1,0)
PTC.attack[2]=gc.newParticleSystem(gc.newImage("/image/attack/2.png"),200)
PTC.attack[2]:setParticleLifetime(.3)
PTC.attack[2]:setEmissionRate(0)
PTC.attack[2]:setSpin(8)
PTC.attack[2]:setColors(1,1,1,.7,1,1,1,0)
PTC.attack[3]=gc.newParticleSystem(gc.newImage("/image/attack/3.png"),200)
PTC.attack[3]:setParticleLifetime(.4)
PTC.attack[3]:setEmissionRate(0)
PTC.attack[3]:setSpin(6)
PTC.attack[3]:setColors(1,1,1,.7,1,1,1,0)
--Attack particles
gc.setCanvas()
c=nil

View File

@@ -17,8 +17,8 @@ function game.main()
collectgarbage()
end
function game.mode()
savedata()
if players then restockRow()end--recycle row used in-game
saveData()
modeSel=modeSel or 1
scene="mode"
curBG="none"
BGM("blank")
@@ -34,17 +34,23 @@ function game.setting()
scene="setting"
curBG="none"
BGM("blank")
end--Normal setting
end
function game.setting2()
scene="setting2"
curBG="none"
keyssetting=nil
curBoard=1
keyboardSet=1
joystickSet=1
keyboardSetting=false
joystickSetting=false
BGM("blank")
end--Advanced setting and keyboard&joystick setting
end--Control settings
function game.setting3()
scene="setting3"
curBG="game1"
sel=nil
keyssetting=nil
snapLevel=1
BGM("blank")
end--Touch setting
function game.help()

199
sysfunc.lua Normal file
View File

@@ -0,0 +1,199 @@
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)
if setting.sfx and not P.ai 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)
break
end
end
sfx[s][n]:setVolume(v or 1)
sfx[s][n]:play()
end
end
function BGM(s)
if setting.bgm and bgmPlaying~=s then
for k,v in pairs(bgm)do v:stop()end
if s then bgm[s]:play()end
bgmPlaying=s
end
end
function gotoScene(s,style)
if not sceneSwaping and s~=scene then
style=style or"deck"
sceneSwaping={
tar=s,style=style,
time=swap[style][1],mid=swap[style][2],
draw=swap[style].d
}
Buttons.sel=nil
end
end
function startGame(mode)
--rec=""
gamemode=mode
gotoScene("play")
end
function back()
local t=prevMenu[scene]
if type(t)=="string"then
gotoScene(t)
else
t()
end
end
function loadData()
userData:open("r")
--local t=string.splitS(love.math.decompress(userdata,"zlib"),"\r\n")
local t=string.splitS(userData:read(),"\r\n")
userData:close()
for i=1,#t do
local i=t[i]
if find(i,"=")then
local t=sub(i,1,find(i,"=")-1)
local v=sub(i,find(i,"=")+1)
if 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
v=toN(v)if not v or v<0 then v=0 end
stat[t]=v
end
end
end
end
function saveData()
local t=table.concat({
stringPack("run=",stat.run),
stringPack("game=",stat.game),
stringPack("gametime=",stat.gametime),
stringPack("piece=",stat.piece),
stringPack("row=",stat.row),
stringPack("atk=",stat.atk),
stringPack("key=",stat.key),
stringPack("rotate=",stat.rotate),
stringPack("hold=",stat.hold),
stringPack("spin=",stat.spin),
},"\r\n")
--t=love.math.compress(t,"zlib"):getString()
userData:open("w")
userData:write(t)
userData:close()
end
function loadSetting()
userSetting:open("r")
--local t=string.splitS(love.math.decompress(userdata,"zlib"),"\r\n")
local t=string.splitS(userSetting:read(),"\r\n")
userSetting:close()
for i=1,#t do
local i=t[i]
if find(i,"=")then
local t=sub(i,1,find(i,"=")-1)
local v=sub(i,find(i,"=")+1)
if t=="sfx"or t=="bgm"then
setting[t]=v=="true"
elseif t=="fullscreen"then
setting.fullscreen=v=="true"
love.window.setFullscreen(setting.fullscreen)
elseif t=="bgblock"then
setting.bgblock=v=="true"
elseif t=="keymap"then
v=string.splitS(v,"/")
for i=1,16 do
local v1=string.splitS(v[i],",")
for j=1,#v1 do
setting.keyMap[i][j]=v1[j]
end
end
elseif t=="keylib"then
v=string.splitS(v,"/")
for i=1,4 do
local v1=string.splitS(v[i],",")
for j=1,#v1 do
setting.keyLib[i][j]=toN(v1[j])
end
for j=1,#setting.keyLib[i]do
local v=setting.keyLib[i][j]
if int(v)~=v or v>=9 or v<=0 then
setting.keyLib[i]={i}
break
end
end
end
elseif t=="virtualkey"then
v=string.splitS(v,"/")
for i=1,9 do
virtualkey[i]=string.splitS(v[i],",")
for j=1,4 do
virtualkey[i][j]=toN(virtualkey[i][j])
end
end
elseif t=="virtualkeyAlpha"then
setting.virtualkeyAlpha=int(abs(toN(v)))
elseif t=="virtualkeyIcon"then
setting.virtualkeyIcon=v=="true"
elseif t=="virtualkeySwitch"then
setting.virtualkeySwitch=v=="true"
elseif t=="frameMul"then
v=min(max(toN(v)or 100,0),100)
setting.frameMul=v
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
setting[t]=int(v)
elseif t=="ghost"or t=="center"then
setting[t]=v=="true"
end
end
end
end
function saveSetting()
local vk={}
for i=1,9 do
for j=1,4 do
virtualkey[i][j]=int(virtualkey[i][j]+.5)
end--Saving a integer is better?
vk[i]=table.concat(virtualkey[i],",")
end--pre-pack virtualkey setting
local map={}
for i=1,16 do
map[i]=table.concat(setting.keyMap[i],",")
end
local lib={}
for i=1,4 do
lib[i]=table.concat(setting.keyLib[i],",")
end
local t=table.concat({
stringPack("sfx=",setting.sfx),
stringPack("bgm=",setting.bgm),
stringPack("fullscreen=",setting.fullscreen),
stringPack("bgblock=",setting.bgblock),
stringPack("das=",setting.das),
stringPack("arr=",setting.arr),
stringPack("sddas=",setting.sddas),
stringPack("sdarr=",setting.sdarr),
stringPack("keymap=",table.concat(map,"/")),
stringPack("keylib=",table.concat(lib,"/")),
stringPack("virtualkey=",table.concat(vk,"/")),
stringPack("virtualkeyAlpha=",setting.virtualkeyAlpha),
stringPack("virtualkeyIcon=",setting.virtualkeyIcon),
stringPack("virtualkeySwitch=",setting.virtualkeySwitch),
stringPack("frameMul=",setting.frameMul),
},"\r\n")
--t=love.math.compress(t,"zlib"):getString()
userSetting:open("w")
userSetting:write(t)
userSetting:close()
end

View File

@@ -1,120 +0,0 @@
function love.update(dt)
--[[
if players then
for k,v in pairs(players[1])do
if rawget(_G,k)then print(k)end
end
end--check player data flew(debugging)
]]
for i=#BGblock,1,-1 do
BGblock[i].y=BGblock[i].y+BGblock[i].v
if BGblock[i].y>720 then rem(BGblock,i)end
end
BGblock.ct=BGblock.ct-1
if BGblock.ct==0 then
ins(BGblock,getNewBlock())
BGblock.ct=rnd(20,30)
end
--Background blocks update
if sceneSwaping then
sceneSwaping.time=sceneSwaping.time-1
if sceneSwaping.time==sceneSwaping.mid then
for i=1,#Buttons[scene]do
Buttons[scene][i].alpha=0
end--Reset buttons' state
game[sceneSwaping.tar]()
Buttons.sel=nil
elseif sceneSwaping.time==0 then
sceneSwaping=nil
end
elseif Tmr[scene]then
Tmr[scene](dt)
end
--scene swapping & Timer
end
function love.receiveData(id,data)
return nil
end
function love.draw()
Pnt.BG[curBG]()
gc.setColor(1,1,1,.3)
for n=1,#BGblock do
local b,img=BGblock[n].b,blockSkin[BGblock[n].bn]
local size=BGblock[n].size
for i=1,#b do for j=1,#b[1]do
if b[i][j]>0 then
gc.draw(img,BGblock[n].x+(j-1)*30*size,BGblock[n].y+(i-1)*30*size,nil,size)
end
end end--Block
end
if Pnt[scene]then Pnt[scene]()end
setFont(40)
drawButton()
if mouseShow and not touching then
gc.setColor(1,1,1)
gc.draw(mouseIcon,mx,my,nil,nil,nil,10,10)
end
if sceneSwaping then sceneSwaping.draw()end
gc.setColor(0,0,0)
if screenM>0 then
gc.rectangle("fill",0,0,1280,-screenM)
gc.rectangle("fill",0,720,1280,screenM)
end--Draw black side
numFont(20)gc.setColor(1,1,1)
gc.print(tm.getFPS(),0,700)
gc.print(gcinfo(),0,680)
--if gcinfo()>500 then collectgarbage()end
end
function love.resize(x,y)
screenK=1280/gc.getWidth()
screenM=(gc.getHeight()*16/9-gc.getWidth())/2
gc.origin()
gc.scale(1/screenK,1/screenK)
gc.translate(0,screenM)
end
function love.run()
local frameT=Timer()
tm.step()
love.resize(nil,gc.getHeight())
game.load()--System scene Launch
math.randomseed(os.time()*626)--true A-lthour's ID!
return function()
love.event.pump()
for name,a,b,c,d,e,f in love.event.poll()do
if name=="quit"then return 0 end
love.handlers[name](a,b,c,d,e,f)
end
if focus then
tm.step()
-- love.receiveData(id,data)
love.update(tm.getDelta())
gc.clear()
love.draw()
gc.present()
if not wd.hasFocus()then
focus=false
ms.setVisible(true)
if bgmPlaying then bgm[bgmPlaying]:pause()end
if scene=="play"then
for i=1,#players[1].keyPressing do
if players[1].keyPressing[i]then
releaseKey(i)
end
end
end
end
else
tm.sleep(.1)
if wd.hasFocus()then
focus=true
ms.setVisible(false)
if bgmPlaying then bgm[bgmPlaying]:play()end
end
end
while Timer()-frameT<1/60 do end
frameT=Timer()
end
end

View File

@@ -1,9 +1,12 @@
setFont(80)
charV=gc.newText(Fonts[80],"v")
local N=gc.newImage
titleImage=N("/image/mess/title.png")
mouseIcon=N("/image/mess/mouseIcon.png")
spinCenter=N("/image/mess/spinCenter.png")
dialCircle=N("/image/mess/dialCircle.png")
dialNeedle=N("/image/mess/dialNeedle.png")
badgeIcon=N("/image/mess/badge.png")
blockSkin={}
for i=1,13 do
blockSkin[i]=N("/image/block/1/"..i..".png")
@@ -17,4 +20,39 @@ background={
virtualkeyIcon={}
for i=1,9 do
virtualkeyIcon[i]=N("/image/virtualkey/"..actName[i]..".png")
end
end
PTC={dust={}}--Particle systems
c=gc.newCanvas(6,6)gc.setCanvas(c)
gc.clear(1,1,1)
PTC.dust[0]=gc.newParticleSystem(c,1000)
PTC.dust[0]:setParticleLifetime(.2,.3)
PTC.dust[0]:setEmissionRate(0)
PTC.dust[0]:setLinearAcceleration(-1500,-200,1500,200)
PTC.dust[0]:setColors(1,1,1,.5,1,1,1,0)
c:release()
--Dust particles
PTC.attack={}
PTC.attack[1]=gc.newParticleSystem(gc.newImage("/image/mess/atk1.png"),200)
PTC.attack[1]:setParticleLifetime(.25)
PTC.attack[1]:setEmissionRate(0)
PTC.attack[1]:setSpin(10)
PTC.attack[1]:setColors(1,1,1,.7,1,1,1,0)
PTC.attack[2]=gc.newParticleSystem(gc.newImage("/image/mess/atk2.png"),200)
PTC.attack[2]:setParticleLifetime(.3)
PTC.attack[2]:setEmissionRate(0)
PTC.attack[2]:setSpin(8)
PTC.attack[2]:setColors(1,1,1,.7,1,1,1,0)
PTC.attack[3]=gc.newParticleSystem(gc.newImage("/image/mess/atk3.png"),200)
PTC.attack[3]:setParticleLifetime(.4)
PTC.attack[3]:setEmissionRate(0)
PTC.attack[3]:setSpin(6)
PTC.attack[3]:setColors(1,1,1,.7,1,1,1,0)
--Attack particles
gc.setCanvas()
c=nil

View File

@@ -33,6 +33,7 @@ function Tmr.load()
elseif loading==4 then
loadnum=loadnum+1
if loadnum==15 then
stat.run=stat.run+1
gotoScene("main")
end
end
@@ -52,6 +53,13 @@ function Tmr.play(dt)
rem(FX.beam,i)
end
end
for i=#FX.badge,1,-1 do
local b=FX.badge[i]
b.t=b.t+1
if b.t==60 then
rem(FX.badge,i)
end
end
for i=1,3 do
PTC.attack[i]:update(dt)
end
@@ -98,7 +106,7 @@ function Tmr.play(dt)
v=0 for i=2,10 do v=v+i*(i-1)*7.2/(frame-dropTime[i])end P.dropSpeed=dropSpeed*.99+v*.1
--Update speeds
if P.ai then
if P.ai and waiting<=0 then
P.ai.controlDelay=P.ai.controlDelay-1
if P.ai.controlDelay==0 then
if #P.ai.controls>0 then
@@ -126,7 +134,7 @@ function Tmr.play(dt)
act[moving>0 and"moveRight"or"moveLeft"](true)
end
else
act[moving>0 and"toRight"or"toLeft"]()
act[moving>0 and"insRight"or"insLeft"]()
end
end
else
@@ -141,7 +149,7 @@ function Tmr.play(dt)
act.down1()
end
else
act.toDown()
act.insDown()
end
end
else
@@ -165,11 +173,14 @@ function Tmr.play(dt)
end
else
if cy~=y_img then
if dropDelay>1 then
if dropDelay>0 then
P.dropDelay=dropDelay-1
else
drop()
P.dropDelay,P.lockDelay=gameEnv.drop,gameEnv.lock
P.dropDelay=gameEnv.drop
if P.freshTime<=gameEnv.freshLimit then
P.lockDelay=gameEnv.lock
end
end
else
if lockDelay>0 then P.lockDelay=lockDelay-1
@@ -177,8 +188,14 @@ function Tmr.play(dt)
end
end
end
if P.b2b>480 then P.b2b=P.b2b-1 end
else--Alive
P.b2b1=P.b2b1*.93+P.b2b*.07
if P.b2b>500 then
P.b2b=P.b2b-.2
elseif P.b2b>100 then
P.b2b=P.b2b-.15
end
--Alive
else
P.keySpeed=keySpeed*.96+cstat.key/time*60*.04
P.dropSpeed=dropSpeed*.96+cstat.piece/time*60*.04
--Final average speeds
@@ -193,13 +210,23 @@ function Tmr.play(dt)
P.clearing={}
end
end--Rows cleared drop
for j=1,#field do for i=1,10 do
if visTime[j][i]<20 then P.visTime[j][i]=visTime[j][i]+.5 end
end end--Make field visible
end--Dead
if P.counter<40 then
for j=1,#field do for i=1,10 do
if visTime[j][i]<20 then P.visTime[j][i]=visTime[j][i]+.5 end
end end--Make field visible
end
if P.b2b1>0 then P.b2b1=max(P.b2b1-3,0)end
--Dead
end
for i=#bonus,1,-1 do
bonus[i].t=bonus[i].t+1
if bonus[i].t>60 then rem(bonus,i)end
if bonus[i].inf then
if bonus[i].t<30 then
bonus[i].t=bonus[i].t+1
end
else
bonus[i].t=bonus[i].t+1
if bonus[i].t==60 then rem(bonus,i)end
end
end
for i=#task,1,-1 do
if task[i]()then rem(task,i)end
@@ -218,7 +245,6 @@ function Tmr.play(dt)
end
end
if fieldBeneath>0 then P.fieldBeneath=fieldBeneath-3 end
P.b2b1=P.b2b1*.95+P.b2b*.05
PTC.dust[p]:update(dt)
end
setmetatable(_G,nil)

66
toolfunc.lua Normal file
View File

@@ -0,0 +1,66 @@
function string.splitS(s,sep)
local t={}
repeat
local i=find(s,sep)or #s+1
ins(t,sub(s,1,i-1))
s=sub(s,i+#sep)
until #s==0
return t
end
function sgn(i)return i>0 and 1 or i<0 and -1 or 0 end--Row numbe is A-uth-or's id!
function stringPack(s,v)return s..toS(v)end
function without(t,v)
for i=1,#t do
if t[i]==v then return nil end
end
return true
end
function mStr(s,x,y)gc.printf(s,x-500,y,1000,"center")end
function convert(x,y)
return x*screenK,(y-screenM)*screenK
end
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
local count=0
BGblockList={}for i=1,16 do BGblockList[i]={v=0}end
function getNewBlock()
count=count+1
if count==17 then count=1 end
local t=BGblockList[count]
t.bn,t.size=BGblock.next,2+3*rnd()
t.b=blocks[t.bn][rnd(0,3)]
t.x=rnd(-#t.b[1]*t.size*30+100,1180)
t.y=-#t.b*30*t.size
t.v=t.size*(1+rnd())
BGblock.next=BGblock.next%7+1
return t
end
function timeSort(a,b)
return a.time>b.time
end
function stencil_field()
gc.rectangle("fill",0,-10,300,610)
end
function stencil_field_small()
gc.rectangle("fill",0,0,300,600)
end
--Single use

View File

@@ -1,53 +0,0 @@
act={
moveLeft=function(auto)
if not auto then P.moving=-1 end
if not ifoverlap(cb,cx-1,cy)then
P.cx=cx-1
freshgho()
freshLockDelay()
if cy==y_img then SFX("move")end
P.spinLast=false
end
end,
moveRight=function(auto)
if not auto then P.moving=1 end
if not ifoverlap(cb,cx+1,cy)then
P.cx=cx+1
freshgho()
freshLockDelay()
if cy==y_img then SFX("move")end
P.spinLast=false
end
end,
hardDrop=function()
if P.waiting<=0 then
if cy~=y_img then
P.cy=y_img
P.spinLast=false
SFX("drop")
end
drop()
P.keyPressing[6]=false
end
end,
softDrop=function()
if cy~=y_img then P.cy=cy-1 end
P.downing=1
end,
rotRight=function()spin(1)end,
rotLeft=function()spin(-1)end,
rotFlip=function()spin(2)end,
hold=hold,
--Player movements
restart=function()
resetGameData()
count=60+26--Althour'z neim
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 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,
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,
quit=function()Event.gameover.lose()end,
--System movements
}