Compare commits

...

9 Commits

Author SHA1 Message Date
MrZ_26
fd5fac4e8a 0.7.32α 2020-02-04 19:37:53 +08:00
MrZ_26
1641440886 0.7.31+α 2020-02-04 19:37:41 +08:00
MrZ_26
c14124d00c 0.7.30α 2020-02-04 19:37:25 +08:00
MrZ_26
f261906f1a 0.7.28+α 2020-02-04 19:37:06 +08:00
MrZ_26
48b68a876b 0.7.27+α 2020-02-04 19:36:54 +08:00
MrZ_26
72040f3855 0.7.25α 2020-02-04 19:36:36 +08:00
MrZ_26
e8f0f4cf38 0.7.24α 2020-02-04 19:36:20 +08:00
MrZ_26
a29fa973a6 Alpha V0.7.23test5 2020-02-04 19:35:50 +08:00
MrZ_26
7b797baf6a Alpha V0.7.22 2020-02-04 19:35:33 +08:00
106 changed files with 7436 additions and 4692 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
BGM/shining terminal.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
SFX/error.ogg Normal file

Binary file not shown.

BIN
SFX/error_long.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
SFX/welcome.ogg Normal file

Binary file not shown.

Binary file not shown.

254
ai.lua
View File

@@ -8,8 +8,78 @@
4deepShape 4deepShape
BlockedWells; BlockedWells;
]] ]]
dirCount={1,1,3,3,3,0,1} local int,ceil,min,abs,rnd=math.floor,math.ceil,math.min,math.abs,math.random
spinOffset={ local ins,rem=table.insert,table.remove
local Timer=love.timer.getTime
-- controlname:
-- 1~5:mL,mR,rR,rL,rF,
-- 6~10:hD,sD,H,A,R,
-- 11~13:LL,RR,DD
local blockPos={4,4,4,4,4,5,4}
local scs={{1,2},{1,2},{1,2},{1,2},{1,2},{1.5,1.5},{0.5,2.5}}
-------------------------------------------------Cold clear
local CCblockID={4,3,5,6,1,2,0}
if system~="Windows"then goto SKIP end
require("CCloader")
BOT={
getConf= cc.get_default_config ,--()options,weights
--setConf= cc.set_options ,--(options,hold,20g,bag7)
new= cc.launch_async ,--(options,weights)bot
addNext= cc.add_next_piece_async ,--(bot,piece)
update= cc.reset_async ,--(bot,field,b2b,combo)
think= cc.request_next_move ,--(bot)
getMove= cc.poll_next_move ,--(bot)success,hold,move
ifDead= cc.is_dead_async ,--(bot)dead
destroy= cc.destroy_async ,--(bot)
setHold= cc.set_hold ,--(opt,bool)
set20G= cc.set_20g ,--(opt,bool)
setBag= cc.set_bag7 ,--(opt,bool)
setNode= cc.set_max_nodes ,--(opt,bool)
free= cc.free ,--(opt/wei)
}
function CC_updateField(P)
local F,i={},1
for y=1,#P.field do
for x=1,10 do
F[i],i=P.field[y][x]>0,i+1
end
end
while i<400 do
F[i],i=false,i+1
end
BOT.update(P.AI_bot,F,P.b2b>=100,P.combo)
end
function CC_switch20G(P)
P.AIdata._20G=true
P.AI_keys={}
BOT.destroy(P.AI_bot)
local opt,wei=BOT.getConf()
BOT.setHold(opt,P.AIdata.hold)
BOT.set20G(opt,P.AIdata._20G)
BOT.setBag(opt,P.AIdata.bag7)
BOT.setNode(opt,P.AIdata.node)
P.AI_bot=BOT.new(opt,wei)
BOT.free(opt)BOT.free(wei)
for i=1,P.AIdata.next do
BOT.addNext(P.AI_bot,CCblockID[P.next[i].id])
end
CC_updateField(P)
P.hd={bk={{}},id=0,color=0,name=0}P.holded=false
P.cur=rem(P.next,1)
P.sc,P.dir=scs[P.cur.id],0
P.r,P.c=#P.cur.bk,#P.cur.bk[1]
P.curX,P.curY=blockPos[P.cur.id],21+ceil(P.fieldBeneath/30)-P.r+min(int(#P.field*.2),2)
P:freshNext()
BOT.addNext(P.AI_bot,CCblockID[P.next[P.AIdata.next].id])
collectgarbage()
end
::SKIP::
-------------------------------------------------⑨Stack setup
local dirCount={1,1,3,3,3,0,1}
local spinOffset={
{1,0,0},--S {1,0,0},--S
{1,0,0},--Z {1,0,0},--Z
{1,0,0},--L {1,0,0},--L
@@ -18,13 +88,7 @@ spinOffset={
{0,0,0},--O {0,0,0},--O
{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
--[[ local FCL={
controlname:
1~5:mL,mR,rR,rL,rF,
6~10:hD,sD,H,A,R,
11~13:LL,RR,DD
]]
FCL={
[1]={ [1]={
{{11},{11,2},{1},{},{2},{2,2},{12,1},{12}}, {{11},{11,2},{1},{},{2},{2,2},{12,1},{12}},
{{11,4},{11,3},{11,2,3},{4},{3},{2,3},{2,2,3},{12,4},{12,3}}, {{11,4},{11,3},{11,2,3},{4},{3},{2,3},{2,2,3},{12,4},{12,3}},
@@ -46,18 +110,17 @@ FCL={
FCL[2]=FCL[1] FCL[2]=FCL[1]
FCL[4]=FCL[3] FCL[4]=FCL[3]
FCL[5]=FCL[3] FCL[5]=FCL[3]
clearScore={[0]=0,0,2,4,12} local clearScore={[0]=0,0,2,4,12}
function ifoverlapAI(f,bk,x,y) local function ifoverlapAI(f,bk,x,y)
if y<1 then return true end if y<1 then return true end
if y>#f then return end if y>#f then return end
for i=1,#bk do for j=1,#bk[1]do for i=1,#bk do for j=1,#bk[1]do
if f[y+i-1]and bk[i][j]and f[y+i-1][x+j-1]>0 then return true end if f[y+i-1]and bk[i][j]and f[y+i-1][x+j-1]>0 then return true end
end end end end
end end
function resetField(f0,f,start) local function resetField(f0,f,start)
::L::if f[start]then while f[start]do
removeRow(f,start) removeRow(f,start)
goto L
end end
for i=start,#f0 do for i=start,#f0 do
f[i]=getNewRow(0) f[i]=getNewRow(0)
@@ -66,7 +129,7 @@ function resetField(f0,f,start)
end end
end end
end end
function getScore(field,bn,cb,cx,cy) local function getScore(field,cb,cy)
local score=0 local score=0
local highest=0 local highest=0
local height=getNewRow(0) local height=getNewRow(0)
@@ -81,12 +144,11 @@ function getScore(field,bn,cb,cx,cy)
clear=clear+1 clear=clear+1
::L:: ::L::
end end
if #field==0 then return 9e99 end--PC best if #field==0 then return 1e99 end--PC best
for x=1,10 do for x=1,10 do
local h=#field local h=#field
::L::if field[h][x]==0 and h>1 then while field[h][x]==0 and h>1 do
h=h-1 h=h-1
goto L
end end
height[x]=h height[x]=h
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
@@ -109,7 +171,8 @@ function getScore(field,bn,cb,cx,cy)
h1=0 h1=0
end end
end end
ins(freeRow,height) freeRow[#freeRow+1]=height
freeRow.L=freeRow.L+1
score= score=
#field*20 #field*20
-cy*35 -cy*35
@@ -120,55 +183,110 @@ function getScore(field,bn,cb,cx,cy)
if mh1>3 then score=score-40-mh1*30 end if mh1>3 then score=score-40-mh1*30 end
return score return score
end end
function AI_getControls(ctrl) -------------------------------------------------
local Tfield={}--test field AI_think={
local field_org=P.field ["9S"]={
for i=1,#field_org do function(P,ctrl)
Tfield[i]=getNewRow(0) local Tfield={}--test field
for j=1,10 do local field_org=P.field
Tfield[i][j]=field_org[i][j] for i=1,#field_org do
end Tfield[i]=getNewRow(0)
end for j=1,10 do
local best={x=1,dir=0,hold=false,score=-9e99} Tfield[i][j]=field_org[i][j]
for ifhold=0,P.gameEnv.hold and 1 or 0 do end
local bn=ifhold==0 and P.cur.id or P.hold.id>0 and P.hold.id or P.next[1].id end
for dir=0,dirCount[bn] do--each dir local best={x=1,dir=0,hold=false,score=-1e99}
local cb=blocks[bn][dir] for ifhold=0,P.gameEnv.hold and 1 or 0 do
for cx=1,11-#cb[1]do--each pos local bn=ifhold==0 and P.cur.id or P.hd.id>0 and P.hd.id or P.next[1].id
local cy=#Tfield+1 for dir=0,dirCount[bn] do--each dir
::L::if not ifoverlapAI(Tfield,cb,cx,cy-1)then local cb=blocks[bn][dir]
cy=cy-1 for cx=1,11-#cb[1]do--each pos
goto L local cy=#Tfield+1
end--move to bottom while not ifoverlapAI(Tfield,cb,cx,cy-1)do
for i=1,#cb do cy=cy-1
local y=cy+i-1 end--move to bottom
if not Tfield[y]then Tfield[y]=getNewRow(0)end for i=1,#cb do
for j=1,#cb[1]do local y=cy+i-1
if cb[i][j]then if not Tfield[y]then Tfield[y]=getNewRow(0)end
Tfield[y][cx+j-1]=1 for j=1,#cb[1]do
end if cb[i][j]then
end Tfield[y][cx+j-1]=1
end--simulate lock end
local score=getScore(Tfield,bn,cb,cx,cy) end
if score>best.score then end--simulate lock
best={bn=bn,x=cx,dir=dir,hold=ifhold==1,score=score} local score=getScore(Tfield,cb,cy)
if score>best.score then
best={bn=bn,x=cx,dir=dir,hold=ifhold==1,score=score}
end
resetField(field_org,Tfield,cy)
end
end end
resetField(field_org,Tfield,cy)
end end
end
end
::L:: ::L::
if #Tfield>0 then if #Tfield>0 then
removeRow(Tfield,1) removeRow(Tfield,1)
goto L goto L
end--Release cache end--Release cache
if best.hold then local p=#ctrl+1
ins(ctrl,8) if best.hold then
end ctrl[p]=8
local l=FCL[best.bn][best.dir+1][best.x] p=p+1
for i=1,#l do end
ins(ctrl,l[i]) local l=FCL[best.bn][best.dir+1][best.x]
end for i=1,#l do
ins(ctrl,6) ctrl[p]=l[i]
end p=p+1
end
ctrl[p]=6
return 2
end,
function(P)
P.AI_delay=P.AI_delay0
if Timer()-P.modeData.point>P.modeData.event then
P.modeData.point=Timer()
P.modeData.event=P.AI_delay0+rnd(2,10)
P:changeAtkMode(rnd()<.85 and 1 or #P.atker>3 and 4 or rnd()<.3 and 2 or 3)
end
return 1
end,
},
["CC"]={
function(P)
if P.AI_needFresh then
CC_updateField(P)
P.AI_needFresh=false
end
BOT.think(P.AI_bot)
return 2
end,--start thinking
function(P,ctrl)
if BOT.ifDead(P.AI_bot)then ins(ctrl,6)return 3 end
local success,hold,move=BOT.getMove(P.AI_bot)
if success then
if hold then ctrl[1]=8 end--Hold
while move[1]do
local m=rem(move,1)
if m<4 then
ins(ctrl,m+1)
elseif not P.AIdata._20G then
ins(ctrl,13)
end
end
ins(ctrl,6)
return 3
else
return 2--stay this stage
end
end,--poll keys
function(P)
P.AI_delay=P.AI_delay0
if Timer()-P.modeData.point>P.modeData.event then
P.modeData.point=Timer()
P.modeData.event=P.AI_delay0+rnd(2,10)
P:changeAtkMode(rnd()<.85 and 1 or #P.atker>3 and 4 or rnd()<.3 and 2 or 3)
end
return 1
end,--check if time to change target
},
}--AI think stage

View File

@@ -1,824 +0,0 @@
local gc,tm=love.graphics,love.timer
local ms,kb,tc=love.mouse,love.keyboard,love.touch
local wd=love.window
local setFont=setFont
local Timer=tm.getTime
local scr=scr
local xOy=love.math.newTransform()
local focus=true
local mx,my,mouseShow=-20,-20,false
local touching=nil--1st touching ID
local sceneInit={
load=function()
loading=1--Loading mode
loadnum=1--Loading counter
loadprogress=0--Loading bar(0~1)
loadTip=text.tips[rnd(#text.tips)]
end,
intro=function()
count=0
BGM("blank")
end,
main=function()
BGM("blank")
collectgarbage()
end,
music=function()
sel=1
BGM()
end,
mode=function()
curBG="none"
saveData()
modeSel=modeSel or 1
levelSel=levelSel or 3
BGM("blank")
end,
custom=function()
optSel=optSel or 1
curBG=customRange.bg[customSel[12]]
BGM(customRange.bgm[customSel[13]])
end,
draw=function()
curBG="none"
kb.setKeyRepeat(true)
clearSureTime=0
pen,sx,sy=1,1,1
end,
play=function()
restartCount=0
if needResetGameData then
resetGameData()
needResetGameData=nil
end
end,
pause=function()
end,
setting=function()
curBG="none"
end,
setting2=function()
curBoard=1
keyboardSet=1
joystickSet=1
keyboardSetting=false
joystickSetting=false
end,--Control settings
setting3=function()
curBG="game1"
defaultSel=1
sel=nil
snapLevel=1
end,--Touch setting
help=function()
end,
stat=function()
end,
quit=function()
love.event.quit()
end,
}
BGblockList={}for i=1,16 do BGblockList[i]={v=0}end
local BGblock={tm=150,next=7,ct=0}
local function getNewBlock()
BGblock.ct=BGblock.ct+1
if BGblock.ct==17 then BGblock.ct=1 end
local t=BGblockList[BGblock.ct]
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 onVirtualkey(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 Buttons.sel then
Buttons.sel=Buttons[scene][Buttons.sel[i]]or Buttons.sel
else
Buttons.sel=select(2,next(Buttons[scene]))
end
elseif i=="space"or i=="return"then
if not sceneSwaping and Buttons.sel then
Buttons.sel.alpha=1
Buttons.sel.code()
SFX("button")
VOICE("nya")
end
end
end
function buttonControl_gamepad(i)
if i=="dpup"or i=="dpdown"or i=="dpleft"or i=="dpright"then
if Buttons.sel then
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
else
Buttons.sel=select(2,next(Buttons[scene]))
end
elseif i=="start"then
if not sceneSwaping and Buttons.sel then
Buttons.sel.alpha=1
Buttons.sel.code()
SFX("button")
VOICE("nya")
end
end
end
local mouseDown,mouseMove,mouseUp,wheelmoved={},{},{},{}
local touchDown,touchUp,touchMove={},{},{}
local keyDown,keyUp={},{}
local gamepadDown,gamepadUp={},{}
function mouseDown.intro(x,y,k)
if k==2 then
back()
else
gotoScene("main")
end
end
function touchDown.intro(id,x,y)
gotoScene("main")
end
function keyDown.intro(key)
if key=="escape"then
back()
else
gotoScene("main")
end
end
function gamepadDown.intro(key)
if key=="back"then
back()
else
gotoScene("main")
end
end
function wheelmoved.mode(x,y)
modeSel=min(max(modeSel+(y>0 and -1 or 1),1),#modeID)
levelSel=ceil(#modeLevel[modeID[modeSel]]*.5)
end
function keyDown.mode(key)
if key=="down"then
if modeSel<#modeID then
modeSel=modeSel+1
levelSel=ceil(#modeLevel[modeID[modeSel]]*.5)
end
elseif key=="up"then
if modeSel>1 then
modeSel=modeSel-1
levelSel=ceil(#modeLevel[modeID[modeSel]]*.5)
end
elseif key=="left"then
if levelSel>1 then
levelSel=levelSel-1
end
elseif key=="right"then
if levelSel<#modeLevel[modeID[modeSel]]then
levelSel=levelSel+1
end
elseif key=="return"then
loadGame(modeSel,levelSel)
elseif key=="c"then
gotoScene("custom")
elseif key=="escape"then
back()
end
end
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
loadGame(modeSel,levelSel)
elseif key=="back"then
back()
end
end
function keyDown.music(key)
if key=="down"then
sel=sel%#musicID+1
elseif key=="up"then
sel=(sel-2)%#musicID+1
elseif key=="return"or key=="space"then
BGM(musicID[sel])
elseif key=="escape"then
back()
end
end
function keyDown.custom(key)
if key=="left"then
customSel[optSel]=(customSel[optSel]-2)%#customRange[customID[optSel]]+1
if optSel==12 then
curBG=customRange.bg[customSel[12]]
elseif optSel==13 then
BGM(customRange.bgm[customSel[13]])
end
elseif key=="right"then
customSel[optSel]=customSel[optSel]%#customRange[customID[optSel]]+1
if optSel==12 then
curBG=customRange.bg[customSel[optSel]]
elseif optSel==13 then
BGM(customRange.bgm[customSel[optSel]])
end
elseif key=="down"then
optSel=optSel%#customID+1
elseif key=="up"then
optSel=(optSel-2)%#customID+1
elseif key=="d"then
gotoScene("draw")
elseif key=="return"then
loadGame(0,1)
elseif key=="space"then
loadGame(0,2)
elseif key=="escape"then
back()
end
end
function mouseDown.draw(x,y,k)
mouseMove.draw(x,y)
end
function mouseMove.draw(x,y,dx,dy)
sx,sy=int((x-200)/30)+1,20-int((y-60)/30)
if sx<1 or sx>10 then sx=nil end
if sy<1 or sy>20 then sy=nil end
if sx and sy and ms.isDown(1,2,3)then
preField[sy][sx]=ms.isDown(1)and pen or ms.isDown(2)and 0 or -1
end
end
function wheelmoved.draw(x,y)
if y<0 then
pen=pen+1
if pen==8 then pen=9 elseif pen==14 then pen=0 end
else
pen=pen-1
if pen==8 then pen=7 elseif pen==-1 then pen=13 end
end
end
function touchDown.draw(id,x,y)
end
function touchMove.draw(id,x,y,dx,dy)
sx,sy=int((x-200)/30)+1,20-int((y-60)/30)
if sx<1 or sx>10 then sx=nil end
if sy<1 or sy>20 then sy=nil end
if sx and sy then
preField[sy][sx]=pen
end
end
function keyDown.draw(key)
if key=="delete"then
Buttons.draw.clear.code()
elseif key=="up"or key=="down"or key=="left"or key=="right"then
if not sx then sx=1 end
if not sy then sy=1 end
if key=="up"and sy<20 then sy=sy+1
elseif key=="down"and sy>1 then sy=sy-1
elseif key=="left"and sx>1 then sx=sx-1
elseif key=="right"and sx<10 then sx=sx+1
end
if kb.isDown("space")then
preField[sy][sx]=pen
end
elseif key=="space"then
if sx and sy then
preField[sy][sx]=pen
end
elseif key=="tab"then
pen=-1
elseif key=="backspace"then
pen=0
elseif key=="escape"then
back()
else
pen=find("123qwea#sdzxc",key)or pen
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,13 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,13)
elseif key=="left"then
curBoard=max(curBoard-1,1)
elseif key=="right"then
curBoard=min(curBoard+1,8)
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 mouseDown.setting3(x,y,k)
if k==2 then back()end
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
function mouseMove.setting3(x,y,dx,dy)
if sel and ms.isDown(1)then
local b=virtualkey[sel]
b[1],b[2]=b[1]+dx,b[2]+dy
end
end
function mouseUp.setting3(x,y,k)
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
function touchDown.setting3(id,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
function touchUp.setting3(id,x,y)
if sel then
x,y=xOy:inverseTransformPoint(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 touchMove.setting3(id,x,y,dx,dy)
if sel then
local b=virtualkey[sel]
b[1],b[2]=b[1]+dx,b[2]+dy
end
end
function keyDown.pause(key)
if key=="escape"then
back()
elseif key=="return"or key=="space"then
resumeGame()
end
end
function touchDown.play(id,x,y)
if setting.virtualkeySwitch then
local t=onVirtualkey(x,y)
if t then
pressKey(t,players[1])
end
end
end
function touchUp.play(id,x,y)
if setting.virtualkeySwitch then
local t=onVirtualkey(x,y)
if t then
releaseKey(t,players[1])
end
end
end
function touchMove.play(id,x,y,dx,dy)
if setting.virtualkeySwitch then
local l=tc.getTouches()
for n=1,#virtualkey do
local b=virtualkey[n]
for i=1,#l do
local x,y=xOy:inverseTransformPoint(tc.getPosition(l[i]))
if(x-b[1])^2+(y-b[2])^2<=b[3]then goto L end
end
releaseKey(n,players[1])
::L::
end
end
end
function keyDown.play(key)
if key=="escape"and not sceneSwaping then
return(frame<180 and back or pauseGame)()
end
local m=setting.keyMap
for p=1,human do
for k=1,12 do
if key==m[2*p-1][k]or key==m[2*p][k]then
pressKey(k,players[p])
return
end
end
end
end
function keyUp.play(key)
local m=setting.keyMap
for p=1,human do
for k=1,12 do
if key==m[2*p-1][k]or key==m[2*p][k]then
releaseKey(k,players[p])
return
end
end
end
end
function gamepadDown.play(key)
if key=="back"then back()return end
local m=setting.keyMap
for p=1,human do
for k=1,12 do
if key==m[2*p+7][k]or key==m[2*p+8][k]then
pressKey(k,players[p])
return
end
end
end
end
function gamepadUp.play(key)
local m=setting.keyMap
for p=1,human do
for k=1,12 do
if key==m[2*p+7][k]or key==m[2*p+8][k]then
releaseKey(k,players[p])
return
end
end
end
end
function love.mousepressed(x,y,k,t,num)
if t then return end
mouseShow=true
mx,my=xOy:inverseTransformPoint(x,y)
if mouseDown[scene]then
mouseDown[scene](mx,my,k)
elseif k==2 then
back()
end
if k==1 then
if not sceneSwaping and Buttons.sel then
local B=Buttons.sel
B.code()
B.alpha=1
Buttons.sel=nil
love.mousemoved(x,y,0,0)
SFX("button")
VOICE("nya")
VIB(1)
end
end
end
function love.mousemoved(x,y,dx,dy,t)
if t then return end
mouseShow=true
mx,my=xOy:inverseTransformPoint(x,y)
Buttons.sel=nil
if mouseMove[scene]then
mouseMove[scene](mx,my,dx/scr.k,dy/scr.k)
end
for _,B in next,Buttons[scene]do
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=B
return
end
end
end
end
function love.mousereleased(x,y,k,t,num)
if t then return end
mx,my=xOy:inverseTransformPoint(x,y)
if mouseUp[scene]then
mouseUp[scene](mx,my,k)
end
end
function love.wheelmoved(x,y)
if wheelmoved[scene]then wheelmoved[scene](x,y)end
end
function love.touchpressed(id,x,y)
mouseShow=false
if not touching then
touching=id
love.touchmoved(id,x,y,0,0)
end
if touchDown[scene]then
touchDown[scene](id,xOy:inverseTransformPoint(x,y))
end
end
function love.touchreleased(id,x,y)
if id==touching then
touching=nil
if Buttons.sel then
local B=Buttons.sel
B.code()
B.alpha=1
Buttons.sel=nil
SFX("button")
VOICE("nya")
VIB(1)
end
Buttons.sel=nil
end
if touchUp[scene]then
touchUp[scene](id,xOy:inverseTransformPoint(x,y))
end
end
function love.touchmoved(id,x,y,dx,dy)
x,y=xOy:inverseTransformPoint(x,y)
if touchMove[scene]then
touchMove[scene](id,x,y,dx/scr.k,dy/scr.k)
end
Buttons.sel=nil
for _,B in next,Buttons[scene]do
if not(B.hide and B.hide())then
if abs(x-B.x)<B.w*.5 and abs(y-B.y)<B.h*.5 then
Buttons.sel=B
return
end
end
end
if not Buttons.sel then
touching=nil
end
end
function love.keypressed(i)
mouseShow=false
if i=="f8"then devMode=not devMode end
if devMode then
if i=="k"then
P=players.alive[rnd(#players.alive)]
P.lastRecv=players[1]
Event.lose()
--Test code here
elseif i=="q"then
local B=Buttons.sel if B then print(format("x=%d,y=%d,w=%d,h=%d",B.x,B.y,B.w,B.h))end
elseif Buttons.sel then
local B=Buttons.sel
if i=="left"then B.x=B.x-10
elseif i=="right"then B.x=B.x+10
elseif i=="up"then B.y=B.y-10
elseif i=="down"then B.y=B.y+10
elseif i==","then B.w=B.w-10
elseif i=="."then B.w=B.w+10
elseif i=="/"then B.h=B.h-10
elseif i=="'"then B.h=B.h+10
end
end
else
if keyDown[scene]then keyDown[scene](i)
elseif i=="escape"or i=="back"then back()
else buttonControl_key(i)
end
end
end
function love.keyreleased(i)
if keyUp[scene]then keyUp[scene](i)
end
end
function love.gamepadpressed(joystick,i)
mouseShow=false
if gamepadDown[scene]then return gamepadDown[scene](i)
elseif i=="back"then 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,valend
function love.joystickhat(js,hat,dirend
function love.sendData(data)end
function love.receiveData(id,data)end
]]
function love.lowmemory()
collectgarbage()
end
function love.resize(w,h)
scr.w,scr.h,scr.r=w,h,h/w
if scr.r>=.5625 then
scr.k=w/1280
scr.x,scr.y=0,(h-w*9/16)*.5
else
scr.k=h/720
scr.x,scr.y=(w-h*16/9)*.5,0
end
gc.origin()
xOy=xOy:setTransformation(w*.5,h*.5,nil,scr.k,nil,640,360)
gc.replaceTransform(xOy)
collectgarbage()
end
function love.focus(f)
if system~="Android" and not f and scene=="play"then pauseGame()end
end
function love.update(dt)
-- if players then for k,v in pairs(players[1])do
-- if rawget(_G,k)and k~="next"and k~="hold"and k~="stat"then print(k,_G[v])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.tm=BGblock.tm-1
if BGblock.tm==0 then
ins(BGblock,getNewBlock())
BGblock.tm=rnd(20,30)
end
end
if sceneSwaping then
sceneSwaping.time=sceneSwaping.time-1
if sceneSwaping.time==sceneSwaping.mid then
for k,B in next,Buttons[scene]do
B.alpha=0
end--Reset buttons' alpha
Buttons.sel=nil
scene=sceneSwaping.tar
sceneInit[scene]()
elseif sceneSwaping.time==0 then
sceneSwaping=nil
end
end
if Tmr[scene]then
Tmr[scene](dt)
end
for i=#Task,1,-1 do
Task[i]:update()
end
if voicePlaying[1]then
if not voicePlaying[1]:isPlaying()then
rem(voicePlaying,1)
end
if voicePlaying[1] and not voicePlaying[1]:isPlaying()then voicePlaying[1]:play()end
end
for k,B in next,Buttons[scene]do
local t=B==Buttons.sel and .4 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
end--update Buttons
end
local scs={1,2,1,2,1,2,1,2,1,2,1.5,1.5,.5,2.5}
function love.draw()
gc.discard()--SPEED UPUPUP!
Pnt.BG[setting.bg and curBG or"grey"]()
gc.setColor(1,1,1,.2)
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]then
gc.draw(img,BGblock[n].x+(j-1)*30*size,BGblock[n].y+(i-1)*30*size,nil,size)
end
end end
end
if Pnt[scene]then Pnt[scene]()end
for k,B in next,Buttons[scene]do
if not(B.hide and B.hide())then
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)
gc.setColor(C)
gc.setLineWidth(3)gc.rectangle("line",B.x-B.w*.5,B.y-B.h*.5,B.w,B.h,4)
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,4)
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-currentFont*.64
gc.printf(t,B.x-201,y0+2,400,"center")
gc.printf(t,B.x-199,y0+2,400,"center")
gc.printf(t,B.x-201,y0,400,"center")
gc.printf(t,B.x-199,y0,400,"center")
gc.setColor(C)
mStr(t,B.x,y0+1)
end
end
end--Draw buttons
if mouseShow and not touching then
local r=Timer()*.5
gc.setColor(1,1,1,min(1-abs(1-r%1*2),.3))
r=int(r)%7+1
gc.draw(mouseBlock[r],mx,my,Timer()%3.1416*4,20,20,scs[2*r]-.5,#blocks[r][0]-scs[2*r-1]+.5)
gc.setColor(1,1,1,.5)gc.circle("fill",mx,my,5)
gc.setColor(1,1,1)gc.circle("fill",mx,my,3)
end--Awesome mouse!
if sceneSwaping then sceneSwaping.draw()end--Swaping animation
if scr.r~=.5625 then
gc.setColor(0,0,0)
if scr.r>.5625 then
local d=(scr.h-scr.w*9/16)*.5/scr.k
gc.rectangle("fill",0,0,1280,-d)
gc.rectangle("fill",0,720,1280,d)
else--high
local d=(scr.w-scr.h*16/9)*.5/scr.k
gc.rectangle("fill",0,0,-d,720)
gc.rectangle("fill",1280,0,d,720)
end--wide
end--Black side
setFont(20)gc.setColor(1,1,1)
gc.print(tm.getFPS(),5,700)
if devMode then
gc.print(mx.." "..my,5,640)
gc.print(#freeRow or 0,5,660)
gc.print(gcinfo(),5,680)
end
end
function love.run()
local frameT=Timer()
local readyDrawFrame=0
local PUMP,POLL=love.event.pump,love.event.poll
love.resize(gc.getWidth(),gc.getHeight())
scene="load"sceneInit.load()--System Launch
return function()
PUMP()
for N,a,b,c,d,e in POLL()do
if N=="quit"then return 0
elseif love[N]then love[N](a,b,c,d,e)end
end
tm.step()
love.update(tm.getDelta())
if not wd.isMinimized()then
readyDrawFrame=readyDrawFrame+setting.frameMul
if readyDrawFrame>=100 then
readyDrawFrame=readyDrawFrame-100
love.draw()
gc.present()
end
end
::L::if Timer()-frameT<1/60 then goto L end
frameT=Timer()
tm.sleep(.001)
end
end

152
class.lua
View File

@@ -1,18 +1,20 @@
local gc=love.graphics
local rem=table.remove
local format=string.format
Task={} Task={}
metatable_task={__index=Task}
function newTask(code,P,data) function newTask(code,P,data)
local obj={ Task[#Task+1]={
code=code, code=code,
P=P, P=P,
data=data, data=data,
} }
setmetatable(obj,metatable_task)
ins(Task,obj)
end end
function clearTask(opt) function clearTask(opt)
if opt=="all"then if opt=="all"then
while Task[1]do local i=#Task
rem(Task,i) while i>0 do
Task[i]=nil
i=i-1
end end
elseif opt=="play"then elseif opt=="play"then
for i=#Task,1,-1 do for i=#Task,1,-1 do
@@ -22,16 +24,142 @@ function clearTask(opt)
end end
else--Player table else--Player table
for i=#Task,1,-1 do for i=#Task,1,-1 do
if Task[i].P==P then if Task[i].P==opt then
rem(Task,i) rem(Task,i)
end end
end end
end end
end end
function Task:update()
if(not self.P or self.P and scene=="play")and self:code(self.P,self.data)then local button={type="button"}
for i=#Task,1,-1 do function newButton(x,y,w,h,color,font,code,hide,N)
if Task[i]==self then rem(Task,i)return end local _={
end--Destroy x=x-w*.5,y=y-h*.5,
w=w,h=h,
color=color,
font=font,
code=code,
hide=hide,
next=N,
}for k,v in next,button do _[k]=v end return _
end
function button:isAbove(x,y)
return x>self.x and x<self.x+self.w and y>self.y and y<self.y+self.h
end
function button:FX()
sysFX[#sysFX+1]={0,0,10,self.x,self.y,self.w,self.h}
--[0=ripple],timer,duration,x,y,w,h
end
function button:draw()
local C=self.color
gc.setColor(C)
gc.setLineWidth(3)gc.rectangle("line",self.x,self.y,self.w,self.h,4)
gc.setColor(C[1],C[2],C[3],.4)
gc.setLineWidth(5)gc.rectangle("line",self.x,self.y,self.w,self.h,4)
if self==widget_sel then
gc.rectangle("fill",self.x,self.y,self.w,self.h,4)
end--Highlight when Selected
local t=self.text
if t then
if type(t)=="function"then t=t()end
setFont(self.font)
local y0=self.y+self.h*.5-self.font*.7
gc.printf(t,self.x-2,y0-1,self.w,"center")
gc.setColor(C)
gc.printf(t,self.x,y0,self.w,"center")
end end
end end
function button:getInfo()
print(format("x=%d,y=%d,w=%d,h=%d,font=%d",self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font))
end
local switch={type="switch"}
function newSwitch(x,y,font,disp,code,hide,N)
local _={
x=x,y=y,font=font,
disp=disp,
code=code,
hide=hide,
next=N,
}for k,v in next,switch do _[k]=v end return _
end
function switch:isAbove(x,y)
return x>self.x and x<self.x+100 and y>self.y-20 and y<self.y+20
end
function switch:FX()
sysFX[#sysFX+1]=self.disp()and
{1,0,15,1,.4,.4,self.x,self.y-20,50,40,0}--Switched on
or{1,0,15,.4,1,.4,self.x+50,self.y-20,50,40,0}--Switched off
--[1=square fade],timer,duration,r,g,b,x,y,w,h
end
function switch:draw()
local x,y=self.x,self.y-20
if self.disp()then
gc.setColor(.6,1,.6)
gc.rectangle("fill",x+50,y,50,40,3)
--ON
else
gc.setColor(1,.6,.6)
gc.rectangle("fill",x,y,50,40,3)
--OFF
end--switch
gc.setColor(1,1,1,self==widget_sel and 1 or .6)
gc.setLineWidth(3)gc.rectangle("line",x-3,y-3,106,46,5)
--frame
local t=self.text
if t then
gc.setColor(1,1,1)
setFont(self.font)
gc.printf(t,x-412,y+20-self.font*.7,400,"right")
end
end
function switch:getInfo()
print(format("x=%d,y=%d,font=%d",self.x,self.y,self.font))
end
local slider={type="slider"}
function newSlider(x,y,w,unit,font,change,disp,code,hide,N)
local _={
x=x,y=y,
w=w,unit=unit,
font=font,
change=change,
disp=disp,
code=code,
hide=hide,
next=N,
}for k,v in next,slider do _[k]=v end return _
end
function slider:isAbove(x,y)
return x>self.x-10 and x<self.x+self.w+10 and y>self.y-20 and y<self.y+20
end
function slider:FX(pos)
sysFX[#sysFX+1]={1,0,10,1,1,1,self.x+self.w*pos/self.unit-8,self.y-15,17,30}
--[1=square fade],timer,duration,r,g,b,x,y,w,h
end
function slider:draw()
local S=self==widget_sel
gc.setColor(1,1,1,S and 1 or .5)
gc.setLineWidth(2)
local x1,x2=self.x,self.x+self.w
for p=0,self.unit do
local x=x1+(x2-x1)*p/self.unit
gc.line(x,self.y+7,x,self.y-7)
end
--units
gc.setLineWidth(5)
gc.line(x1,self.y,x2,self.y)
--axis
gc.setColor(1,1,1)
gc.rectangle("fill",x1+(x2-x1)*self.disp()/self.unit-8,self.y-15,17,30)
--block
local t=self.text
if t then
gc.setColor(1,1,1)
setFont(self.font)
gc.printf(t,self.x-312,self.y-self.font*.7,300,"right")
end
end
function slider:getInfo()
print(format("x=%d,y=%d,w=%d",self.x,self.y,self.w))
end

View File

@@ -1,21 +1,27 @@
math.randomseed(os.time())
gameVersion="Alpha V0.7.32"
function love.conf(t) function love.conf(t)
local X=nil
t.identity="Techmino"--Save directory name t.identity="Techmino"--Save directory name
t.appendidentity=X--If search files in source before save directory
t.version="11.1" t.version="11.1"
t.console=X t.console=X
t.accelerometerjoystick=X--If exposing accelerometer on iOS and Android as a Joystick
t.gammacorrect=X t.gammacorrect=X
t.appendidentity=X--If search files in source before save directory
t.accelerometerjoystick=X--If exposing accelerometer on iOS and Android as a Joystick
t.audio.mixwithsystem=true--Switch on to keep sysBGM t.audio.mixwithsystem=true--Switch on to keep sysBGM
local W=t.window local W=t.window
W.title="Techmino V0.7.21" if math.random()>.26 then
W.title="Techmino "..gameVersion
else
math.randomseed(tonumber(os.date("%Y%j")))
W.title="Your lucky number today:"..math.random(100,626)
end
W.icon="/image/icon.png" W.icon="/image/icon.png"
W.width,W.height=1280,720 W.width,W.height=1280,720
W.minwidth,W.minheight=640,360 W.minwidth,W.minheight=640,360
W.borderless=X W.borderless=X
W.resizable=true W.resizable=1
W.fullscreentype="desktop"--Choose between "desktop" fullscreen or "exclusive" fullscreen mode (string) W.fullscreentype="desktop"--"exclusive"
W.fullscreen=X W.fullscreen=X
W.vsync=0--0→∞fps W.vsync=0--0→∞fps
W.msaa=X--The number of samples to use with multi-sampled antialiasing (number) W.msaa=X--The number of samples to use with multi-sampled antialiasing (number)
@@ -26,23 +32,10 @@ function love.conf(t)
W.x,W.y=nil W.x,W.y=nil
local M=t.modules local M=t.modules
M.window=true M.window,M.system,M.event=1,1,1
M.system=true M.audio,M.sound=1,1
M.audio=true M.math,M.data=1,1
M.data=true M.timer,M.graphics,M.font,M.image=1,1,1,1
M.event=true M.mouse,M.touch,M.keyboard,M.joystick=1,1,1,1
M.font=true M.physics,M.thread,M.video=X
M.graphics=true
M.image=true
M.joystick=true
M.keyboard=true
M.math=true
M.mouse=true
M.sound=true
M.timer=true
M.touch=true
M.physics=X
M.thread=X
M.video=X
end end

File diff suppressed because it is too large Load Diff

97
default_data.lua Normal file
View File

@@ -0,0 +1,97 @@
setting={
das=10,arr=2,
sddas=0,sdarr=2,
quickR=true,swap=true,
fine=false,
--game
ghost=true,center=true,
smo=true,grid=false,
dropFX=3,
shakeFX=3,
atkFX=3,
frameMul=100,
--
fullscreen=false,
bg=true,
bgblock=true,
lang=1,
skin=1,
--graphic
sfx=10,bgm=7,
vib=3,voc=0,
stereo=6,
--sound
keyMap={
{"left","right","x","z","c","up","down","space","tab","r"},
{},{},{},{},{},{},{},
--keyboard
{"dpleft","dpright","a","b","y","dpup","dpdown","rightshoulder","x","leftshoulder"},
{},{},{},{},{},{},{},
--joystick
},
VKSwitch=true,
VKTrack=true,--If tracked
VKDodge=false,--If repel
VKTchW=3,--Touch Weight
VKCurW=4,--CurPos Weight
VKIcon=true,
VKAlpha=3,
--control
}
local L=setting.keyMap
for i=1,#L do
for j=1,20 do
if not L[i][j]then
L[i][j]=""
end
end
end
stat={
run=0,game=0,time=0,
extraPiece=0,extraRate=0,
key=0,rotate=0,hold=0,piece=0,row=0,
atk=0,send=0,recv=0,pend=0,
clear_1=0,clear_2=0,clear_3=0,clear_4=0,
spin_0=0,spin_1=0,spin_2=0,spin_3=0,
b2b=0,b3b=0,pc=0,score=0,
}
--Things related to virtualkey
function restoreVirtualKey()
for i=1,#VK_org do
local B,O=virtualkey[i],VK_org[i]
B.ava=O.ava
B.x=O.x
B.y=O.y
B.r=O.r
end
end
local O,_=true,false
VK_org={--Original set,for restore VK' position
{ava=O,x=80, y=720-200, r=80},--moveLeft
{ava=O,x=320, y=720-200, r=80},--moveRight
{ava=O,x=1280-80, y=720-200, r=80},--rotRight
{ava=O,x=1280-200, y=720-80, r=80},--rotLeft
{ava=O,x=1280-200, y=720-320, r=80},--rotFlip
{ava=O,x=200, y=720-320, r=80},--hardDrop
{ava=O,x=200, y=720-80, r=80},--softDrop
{ava=O,x=1280-320, y=720-200, r=80},--hold
{ava=O,x=1280-80, y=280, r=80},--func
{ava=O,x=80, y=280, r=80},--restart
{ava=_,x=100, y=50, r=80},--insLeft
{ava=_,x=200, y=50, r=80},--insRight
{ava=_,x=300, y=50, r=80},--insDown
{ava=_,x=400, y=50, r=80},--down1
{ava=_,x=500, y=50, r=80},--down4
{ava=_,x=600, y=50, r=80},--down10
{ava=_,x=700, y=50, r=80},--dropLeft
{ava=_,x=800, y=50, r=80},--dropRight
{ava=_,x=900, y=50, r=80},--addToLeft
{ava=_,x=1000, y=50, r=80},--addToRight
}
virtualkey={}
for i=1,#VK_org do
virtualkey[i]={}
end

89
document.txt Normal file
View File

@@ -0,0 +1,89 @@
游戏方法:
控制系统提供的一个个方块,每填满场地的一行就会将其消除,根据消除方式会给对手攻击(如果有对手的话)
完成当前游戏模式中的目标或者是活到最后即算胜利.
旋转系统:
使用Techmino专属旋转系统,细节不赘述
spin判定:
结合了不可移动判定和三角判定,是否为mini也与这二者有关,细节不赘述
攻击系统:
消1/2/3/4攻击0/1/2/4
spin1/2/3攻击2/4/6,若mini则减半
b2b:增加1~2(tetris)/1~3(spin)攻击
b3b:满b2b效果+1额外抵挡
PC:其它攻击与6~8(本局内递增)取高+2额外抵挡
连击:0,0,1,1,2,2,3,3,4,4,3……
back to back(B2B)点数说明:
B2B点数的范围在0~1200
在40及以上特殊消除时B2B,在1000以上特殊消除时B3B,1200封顶
消四+100
空spin加20,不超过1000
spin1~3+50/100/180 (mini*.5)
普通消除-250
1000以上空放一块-40(不减到低于1000)
攻击延迟:
消2/3的攻击生效最快,消四其次,spin攻击生效较慢,高连击生效最慢
b2b或者b3b增加攻击力的同时也会减缓一点生效速度,mini大幅减缓生效速度
抵消逻辑:
发动攻击时,若缓冲条有攻击则先用额外抵挡再用攻击力1:1抵消最先受到的攻击
没有用上的额外抵挡会被丢弃,最后剩下的攻击力会发送给对手
模式说明:
竞速:
用你最快的速度消除40行(据难度而定)吧!
马拉松:
根据总消行数,速度会逐渐加快,消除两百行吧!(easy和hard就是normal开始和结束的速度,消除200行不加速)
大师:
马拉松进化版,如果觉得马拉松太简单了久玩这个吧,每一个难度都是一层境界,L难度和U难度攒到500点数通关,final难度为上级者专属游戏模式,不建议游玩.
经典:
使用低速控制设置在高速下落时尽可能消除更多的行,没有通关目标.(到90有"彩蛋")
禅:
闲得无聊,只是想单纯地打打块地时候可以玩此模式,无重力消除200行.
无尽:
无尽模式,边上会显示玩家的消行数和攻击效率,适合科研(术语).
单挑:
和一个电脑玩家单挑,带加号的和最后一个模式是超强机器人(仅限Windows平台),试试你能稳定打败多难的对手吧!
回合制:
玩法同单挑模式,只不过只有当一个人放下一个方块后另一个人才能放下一块.
仅TSD:
这个模式中,玩家必须用TSD(T spin double)的方式消除,否则直接判负,你能连续打出多少个TSD呢?
隐形:
根据不同难度,场地内(甚至当前方块)会隐形,看看你能活多久吧!(GM难度为类似TGM3的GM Roll,用于上级者练习)
挖掘:
每隔一定时间,系统会向场地的低端添加一行垃圾行,间隔会随着波数增加而越来越短,你能顶住几波呢?
生存:
每隔一定时间,系统会向玩家的垃圾缓冲槽中添加垃圾行,释放速度和间隔会随着波数增加而越来越短,玩家可以将其抵消也可以让其释放,尽可能活更久的时间.
防守:
系统会向玩家的垃圾缓冲槽中添加难消除的垃圾行,释放速度和间隔会随着波数增加而越来越短,玩家要尽量抵消他们来让自己存活更久.
进攻:
当玩家的攻击缓冲槽空时,系统会向玩家的垃圾缓冲槽中添加大量的垃圾行(高难度下后期甚至会远超过20),释放速度和间隔都会随着波数增加而越来越短,垃圾上涨速度也会提升.赶紧在其释放之前将攻击抵消到不会一下致命的量!
科研:
玩家只被允许做特殊消除(spin/全消/消四),在带+的难度中不允许消四,U难度下玩家甚至只被允许每一个方块都使用最简操作控制,任何违反规则的行为都会判负.
C4W练习:(或者说是4w练习)
系统直接提供给玩家"留4列"的场地,玩家可以自由练习4w消除,该技巧在某些时候实战很有用.(需要学会spin,否则意义不是很大)
全清训练:
系统会连续给玩家提供"标准开局PC套路"的场地和四个方块(不允许使用hold),玩家需要一直完成PC,否则判负.
全清挑战:
在消除一百行的限制内,你能全清几次?
49人混战:
许多玩家同时进行一局游戏其它的是AI,不是真人).随着玩家数量的减少,方块下落/垃圾生效速度/垃圾升起速度都会增加.淘汰其它玩家后可以获得一个徽章和该玩家持有的徽章,增强自己的攻击力.
玩家可选四个攻击模式:
1.随机:每次攻击后10%随机挑选一个玩家锁定
2.最多徽章:攻击后或者锁定玩家死亡时锁定徽章最多的玩家
3.最高:攻击后或者锁定玩家死亡时锁定场地最高的玩家(每秒刷新)
4.反击:攻击所有锁定自己的玩家AOE,若无则伏击随机玩家
坚持到最后的玩家就是胜利者.
99人混战:
同49人混战,只是增加到了99名玩家,难度系数也有调整,对设备的要求也较高.
干旱:
系统提供的方块序列变得奇怪了!你能消除100行不死吗,或者,多快?
多人:
使用键盘或者多个手柄(也许?)
自定义:
玩家可以自由调整下落速度等等几乎大多数设置(不包括上述各种游戏模式的特殊效果),也可以画一个场地去消除或者是作为提示模板来玩方块拼图.在拼图模式下,按功能键切换是否显示提示模板.其中打"X"的格子不允许有方块,空的格子可以是任何状态,玩家能获得的七种普通方块必须完全符合,垃圾行方块的为止只要有方块就可以,但是不能是空气,玩家拼出自己画的图后就会判定胜利.

BIN
font.ttf

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 973 B

BIN
image/mess/charge.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

BIN
image/mess/power.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 972 B

After

Width:  |  Height:  |  Size: 961 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

BIN
image/virtualkey.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

View File

@@ -1,3 +1,13 @@
local BK="返回"
local actName={
"左移:","右移:",
"顺时针旋转:","逆时针旋转:","180°旋转:",
"硬降:","软降:",
"暂存:","功能键:",
"重新开始:",
"左瞬移:","右瞬移:","软降到底:","软降一格:","软降四格:","软降十格:",
"落在最左:","落在最右:","列在最左:","列在最右:",
}
return{ return{
atkModeName={"随机","徽章","击杀","反击"}, atkModeName={"随机","徽章","击杀","反击"},
royale_remain=function(n)return"剩余 "..n.." 名玩家"end, royale_remain=function(n)return"剩余 "..n.." 名玩家"end,
@@ -13,7 +23,10 @@ return{
PC="Perfect Clear", PC="Perfect Clear",
hold="暂存",next="下一个", hold="暂存",next="下一个",
stage={"关卡 1","关卡 2","关卡 3","关卡 4","关卡 5",}, stage=function(n)return"关卡 "..n end,
great="Great!",
awesome="Awesome.",
continue="Continue.",
maxspeed="最高速度", maxspeed="最高速度",
speedup="速度加快", speedup="速度加快",
@@ -21,7 +34,7 @@ return{
lose="失败", lose="失败",
pause="暂停", pause="暂停",
finish="结束", finish="结束",
pauseTime="暂停时间", pauseCount="暂停统计",
custom="自定义游戏", custom="自定义游戏",
customOption={ customOption={
@@ -40,7 +53,7 @@ return{
bgm="背景音乐:", bgm="背景音乐:",
}, },
customVal={ customVal={
drop={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,"","[20G]"}, drop={"[20G]",1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,""},
lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,""}, lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,""},
wait=nil, wait=nil,
fall=nil, fall=nil,
@@ -50,21 +63,28 @@ return{
visible={"可见","半隐","全隐","瞬隐"}, visible={"可见","半隐","全隐","瞬隐"},
target={10,20,40,100,200,500,1000,""}, target={10,20,40,100,200,500,1000,""},
freshLimit={0,8,15,""}, freshLimit={0,8,15,""},
opponent={"无电脑",1,2,3,4,5,6,7,8,9,10,11}, opponent={"无电脑","9S Lv1","9S Lv2","9S Lv3","9S Lv4","9S Lv5","CC Lv1","CC Lv2","CC Lv3","CC Lv4","CC Lv5","CC Lv6"},
}, },
softdropdas="软降DAS:", softdropdas="软降DAS:",
softdroparr="软降ARR:", softdroparr="软降ARR:",
snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"}, snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"},
keyboard="键盘",joystick="手柄", keyboard="键盘",joystick="手柄",
space="空格",enter="回车", space="空格",enter="回车",
setting2Help="方向键选择/翻页,回车修改,esc返回", ctrlSetHelp="方向键选择/翻页,回车修改,esc返回",
setting_game="游戏设置",
setting_graphic="画面设置",
setting_sound="声音设置",
musicRoom="音乐室", musicRoom="音乐室",
nowPlaying="正在播放:", nowPlaying="正在播放:",
VKTchW="触摸点权重",
VKOrgW="原始点权重",
VKCurW="当前点权重",
actName={"左移:","右移:","顺时针旋转:","逆时针旋转:","180°旋转","硬降:","软降:","暂存:","功能键:","重新开始:","左瞬移:","右瞬移:","软降到底:"}, actName=actName,
modeName={ modeName={
[0]="自定义", [0]="自定义",
"竞速","马拉松","大师","经典","","无尽","单挑","仅TSD","隐形","挖掘","生存","科研", "竞速","马拉松","大师","经典","","无尽","单挑","回合制","仅TSD","隐形",
"挖掘","生存","防守","进攻","科研",
"C4W练习","全清训练","全清挑战","49人混战","99人混战","干旱","多人", "C4W练习","全清训练","全清挑战","49人混战","99人混战","干旱","多人",
}, },
modeInfo={ modeInfo={
@@ -75,10 +95,13 @@ return{
zen="无重力消除200行", zen="无重力消除200行",
infinite="科研沙盒", infinite="科研沙盒",
solo="打败AI", solo="打败AI",
round="下棋",
tsd="尽可能做TSD", tsd="尽可能做TSD",
blind="最强大脑", blind="最强大脑",
dig="核能挖掘机", dig="核能挖掘机",
survivor="防守练习", survivor="你能存活多久?",
defender="防守练习",
attacker="进攻练习",
tech="尽可能不要普通消除", tech="尽可能不要普通消除",
c4wtrain="无 限 连 击", c4wtrain="无 限 连 击",
pctrain="熟悉全清定式的组合", pctrain="熟悉全清定式的组合",
@@ -92,27 +115,35 @@ return{
load={"加载语音ing","加载音乐ing","加载音效ing","加载完成",}, load={"加载语音ing","加载音乐ing","加载音效ing","加载完成",},
tips={ tips={
"不是动画,真的在加载!", "不是动画,真的在加载!",
"整个游戏都是MrZ完成的!",
"大满贯10连击消四全清!", "大满贯10连击消四全清!",
"<方块研究所>有一个Nspire-CX版本!", "<方块研究所>有一个Nspire-CX版本!",
"B2B2B???",
"B2B2B2B存在吗?", "B2B2B2B存在吗?",
"MEGACMB!", "MEGACMB!",
"ALLSPIN!", "ALLSPIN!",
"O型回旋三清?", "O spin triple!",
"只用一个输入设备就可以游玩了",
"Miya:喵!", "Miya:喵!",
"225238922,哔哩哔哩 干杯~", "225238922 哔哩哔哩 干杯~",
"适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活", "适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活",
"合群了就会消失,但是消失不代表没有意义", "合群了就会消失,但是消失不代表没有意义",
"学会使用两个旋转键,三个更好", "学会使用两个旋转键,三个更好",
"更小的DAS和ARR拥有更高的操作上限", "更小的DAS和ARR拥有更高的操作上限(如果你还能控制得了的话)",
"注意到\"旋转\"到底对方块做了些什么吗?", "注意到\"旋转\"到底对方块做了些什么吗?",
"20G是一套全新的游戏规则", "20G本质是一套全新的游戏规则",
"不要在上课时玩游戏!", "不要在上课时玩游戏!",
"本游戏难度上限很高,做好心理准备", "本游戏难度上限很高,做好心理准备",
"方块可以不是个休闲游戏", "方块可以不是个休闲游戏",
"调到特殊的日期也不会发生什么的", "调到特殊的日期也不会发生什么的",
"[随机文本]", "3.1415926535897932384",
"2.7182818284590452353",
"Let-The-Bass-Kick!",
"使用love2d引擎制作",
"有疑问?先看设置有没有你想要的",
"有建议的话可以把信息反馈给作者~",
"不要按F8",
"秘密代码:626",
"CLASSIC SEXY RUSSIAN BLOCKS",
"LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI
}, },
stat={ stat={
"游戏运行次数:", "游戏运行次数:",
@@ -132,6 +163,8 @@ return{
"B2B数:", "B2B数:",
"PC数:", "PC数:",
"效率:", "效率:",
"多余操作:",
"最简操作率:",
}, },
help={ help={
"好像也没啥好帮助的吧?就当是关于了", "好像也没啥好帮助的吧?就当是关于了",
@@ -142,14 +175,25 @@ return{
"使用LOVE2D引擎", "使用LOVE2D引擎",
"作者:MrZ 邮箱:1046101471@qq.com", "作者:MrZ 邮箱:1046101471@qq.com",
"程序:MrZ 美术:MrZ 音乐:MrZ 音效:MrZ 语音:Miya", "程序:MrZ 美术:MrZ 音乐:MrZ 音效:MrZ 语音:Miya",
"使用工具:VScode,GFIE,Beepbox,Goldwave", "特别感谢:Farter,Flyz,196,Teatube,T830,[所有测试人员]和 你!",
"特别感谢:Farter,196,Teatube,Flyz,T830,[所有测试人员]和 你!",
"错误或者建议请附带相关信息发送到作者邮箱~", "错误或者建议请附带相关信息发送到作者邮箱~",
}, },
used=[[
使用工具:
Beepbox
GFIE
Goldwave
使用库:
Cold_Clear[MinusKelvin]
simple-love-lights[dylhunn]
]],
support="支持作者", support="支持作者",
group="官方QQ群", group="官方QQ群",
ButtonText={ warning="禁 止 私 自 传 播",
WidgetText={
main={ main={
lang="文-Lang",
qplay="快速开始",
play="开始", play="开始",
setting="设置", setting="设置",
music="音乐室", music="音乐室",
@@ -164,13 +208,14 @@ return{
right="", right="",
start="开始", start="开始",
custom="自定义(C)", custom="自定义(C)",
back="返回", back=BK,
}, },
music={ music={
bgm="BGM",
up="", up="",
play="播放", play="播放",
down="", down="",
back="返回", back=BK,
}, },
custom={ custom={
up="", up="",
@@ -180,81 +225,122 @@ return{
start1="消除开始", start1="消除开始",
start2="拼图开始", start2="拼图开始",
draw="画图(D)", draw="画图(D)",
set1="40行", set1="40行(1)",
set2="1v1", set2="1v1(2)",
set3="无尽", set3="无尽(3)",
set4="隐形", set4="隐形(4)",
set5="极限", set5="极限(5)",
back="返回", back=BK,
}, },
draw={ draw={
any="不定", any="不定",
block1="", block1="Z",
block2="", block2="S",
block3="", block3="L",
block4="", block4="J",
block5="", block5="T",
block6="", block6="O",
block7="", block7="I",
gb1="", gb1="",
gb2="", gb2="",
gb3="", gb3="",
gb4="", gb4="",
gb5="", gb5="",
space="×", space="×",
clear="", clear="",
back="返回", back=BK,
}, },
play={ play={
pause="暂停", pause="暂停",
}, },
pause={ pause={
resume="继续", resume= "继续",
quit="退出", restart="重新开始",
setting="设置",
quit= "退出",
}, },
setting={ setting_game={
ghost=function()return setting.ghost and"阴影:开"or"阴影:关"end, graphic="←画面设置",
center=function()return setting.center and"旋转中心:开"or"旋转中心:关"end, sound="声音设置→",
grid=function()return setting.grid and"网格:开"or"网格:关"end,
swap=function()return setting.swap and"目标选择:组合键"or"目标选择:循环"end,
fxs=function()return setting.fxs and"特效:开"or"特效:关"end,
bg=function()return setting.bg and"背景:开"or"背景:关"end,
dasD="-",dasU="+", dasD="-",dasU="+",
arrD="-",arrU="+", arrD="-",arrU="+",
sddasD="-",sddasU="+", sddasD="-",sddasU="+",
sdarrD="-",sdarrU="+", sdarrD="-",sdarrU="+",
ctrl="控制设置", quickR="快速重新开始",
touch="触摸设置", swap="组合键切换攻击模式",
lang=function()return langName[setting.lang]end, fine="极简操作提示音",
sfx=function()return setting.sfx and"音效:开"or"音效:关"end, ctrl="键位设置",
bgm=function()return setting.bgm and"音乐:开"or"音乐:关"end, touch="触屏设置",
vib=function()return "震动:"..setting.vib end, back=BK,
voc=function()return setting.voc and"语音:开"or"语音:关"end,
fullscreen=function()return setting.fullscreen and"全屏:开"or"全屏:关"end,
bgblock=function()return setting.bgblock and"背景动画:开"or"背景动画:关"end,
frame=function()return"绘制帧:"..setting.frameMul.."%"end,
skin="切换方块皮肤",
back="保存&返回",
}, },
setting2={ setting_graphic={
back="返回", sound="←声音设置",
game="游戏设置→",
ghost="阴影",
grid="网格",
center="旋转中心",
skin="皮肤",
bg="背景",
bgblock="背景动画",
smo="平滑下落",
dropFX="下落特效等级",
shakeFX="晃动特效等级",
atkFX="攻击特效等级",
fullscreen="全屏",
frame="绘制帧率",
back=BK,
}, },
setting3={ setting_sound={
back="返回", game="←游戏设置",
hide=function()return setting.virtualkeySwitch and"隐藏虚拟按键"or"显示虚拟按键"end, graphic="画面设置→",
sfx="音效",
bgm="音乐",
vib="震动",
voc="语音",
back=BK,
},
setting_key={
back=BK,
},
setting_touch={
hide="显示虚拟按键",
track="按键自动跟踪",
tkset="跟踪设置",
default="默认组合", default="默认组合",
snap=function()return text.snapLevelName[snapLevel]end, snap=function()return text.snapLevelName[snapLevel]end,
alpha=function()return percent0to5[setting.virtualkeyAlpha]end, alpha=function()return setting.VKAlpha.."0%"end,
icon="图标", icon="图标",
size="大小", size="大小",
toggle="开关",
back=BK,
},
setting_touchSwitch={
b1= actName[1],b2=actName[2],b3=actName[3],b4=actName[4],
b5= actName[5],b6=actName[6],b7=actName[7],b8=actName[8],
b9= actName[9],b10=actName[10],b11=actName[11],b12=actName[12],
b13=actName[13],b14=actName[14],b15=actName[15],b16=actName[16],
b17=actName[17],b18=actName[18],b19=actName[19],b20=actName[20],
norm="标准",
pro="专业",
back=BK,
},
setting_trackSetting={
VKDodge="自动避让",
back=BK,
}, },
help={ help={
back="返回", his="历史",
qq="作者QQ", qq="作者QQ",
back=BK,
},
history={
prev="",
next="",
back=BK,
}, },
stat={ stat={
back="返回",
path="打开存储目录", path="打开存储目录",
back=BK,
}, },
}, },
} }--文

View File

@@ -1,3 +1,13 @@
local BK="返回"
local actName={
"左移:","右移:",
"顺时针旋转:","逆时针旋转:","180°旋转:",
"硬降:","软降:",
"暂存:","功能键:",
"重新开始:",
"左瞬移:","右瞬移:","软降到底:","软降一格:","软降四格:","软降十格:",
"落在最左:","落在最右:","列在最左:","列在最右:",
}
return{ return{
atkModeName={"随机","徽章","击杀","反击"}, atkModeName={"随机","徽章","击杀","反击"},
royale_remain=function(n)return"剩余 "..n.." 名玩家"end, royale_remain=function(n)return"剩余 "..n.." 名玩家"end,
@@ -13,7 +23,10 @@ return{
PC="场地全清", PC="场地全清",
hold="暂存",next="下一个", hold="暂存",next="下一个",
stage={"关卡 1","关卡 2","关卡 3","关卡 4","关卡 5",}, stage=function(n)return"关卡 "..n end,
great="不错!",
awesome="精彩。",
continue="继续。",
maxspeed="最高速度", maxspeed="最高速度",
speedup="速度加快", speedup="速度加快",
@@ -21,7 +34,7 @@ return{
lose="失败", lose="失败",
pause="暂停", pause="暂停",
finish="结束", finish="结束",
pauseTime="暂停时间", pauseCount="暂停统计",
custom="自定义游戏", custom="自定义游戏",
customOption={ customOption={
@@ -40,7 +53,7 @@ return{
bgm="背景音乐:", bgm="背景音乐:",
}, },
customVal={ customVal={
drop={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,"","[20G]"}, drop={"[20G]",1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,""},
lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,""}, lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,""},
wait=nil, wait=nil,
fall=nil, fall=nil,
@@ -50,21 +63,28 @@ return{
visible={"可见","半隐","全隐","瞬隐"}, visible={"可见","半隐","全隐","瞬隐"},
target={10,20,40,100,200,500,1000,""}, target={10,20,40,100,200,500,1000,""},
freshLimit={0,8,15,""}, freshLimit={0,8,15,""},
opponent={"无电脑",1,2,3,4,5,6,7,8,9,10,11}, opponent={"无电脑","9S Lv1","9S Lv2","9S Lv3","9S Lv4","9S Lv5","CC Lv1","CC Lv2","CC Lv3","CC Lv4","CC Lv5","CC Lv6"},
}, },
softdropdas="软降DAS:", softdropdas="软降DAS:",
softdroparr="软降ARR:", softdroparr="软降ARR:",
snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"}, snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"},
keyboard="键盘",joystick="手柄", keyboard="键盘",joystick="手柄",
space="空格",enter="回车", space="空格",enter="回车",
setting2Help="方向键选择/翻页,回车修改,esc返回", ctrlSetHelp="方向键选择/翻页,回车修改,esc返回",
setting_game="游戏设置",
setting_graphic="画面设置",
setting_sound="声音设置",
musicRoom="音乐室", musicRoom="音乐室",
nowPlaying="正在播放:", nowPlaying="正在播放:",
VKTchW="触摸点权重",
VKOrgW="原始点权重",
VKCurW="当前点权重",
actName={"左移:","右移:","顺时针旋转:","逆时针旋转:","180°旋转","硬降:","软降:","暂存:","功能键:","重新开始:","左瞬移:","右瞬移:","软降到底:"}, actName=actName,
modeName={ modeName={
[0]="自定义", [0]="自定义",
"竞速","马拉松","大师","经典","","无尽","单挑","仅TSD","隐形","挖掘","生存","科研", "竞速","马拉松","大师","经典","","无尽","单挑","回合制","仅TSD","隐形",
"挖掘","生存","防守","进攻","科研",
"C4W练习","全清训练","全清挑战","49人混战","99人混战","干旱","多人", "C4W练习","全清训练","全清挑战","49人混战","99人混战","干旱","多人",
}, },
modeInfo={ modeInfo={
@@ -75,10 +95,13 @@ return{
zen="无重力消除200行", zen="无重力消除200行",
infinite="科研沙盒", infinite="科研沙盒",
solo="打败AI", solo="打败AI",
round="下棋",
tsd="尽可能做T旋双清", tsd="尽可能做T旋双清",
blind="最强大脑", blind="最强大脑",
dig="核能挖掘机", dig="核能挖掘机",
survivor="防守练习", survivor="你能存活多久?",
defender="防守练习",
attacker="进攻练习",
tech="尽可能不要普通消除!", tech="尽可能不要普通消除!",
c4wtrain="无 限 连 击", c4wtrain="无 限 连 击",
pctrain="熟悉全清定式的组合", pctrain="熟悉全清定式的组合",
@@ -92,27 +115,35 @@ return{
load={"加载语音ing","加载音乐ing","加载音效ing","加载完成",}, load={"加载语音ing","加载音乐ing","加载音效ing","加载完成",},
tips={ tips={
"不是动画,真的在加载!", "不是动画,真的在加载!",
"整个游戏都是MrZ完成的!",
"大满贯10连击消四全清!", "大满贯10连击消四全清!",
"<方块研究所>有一个Nspire-CX版本!", "<方块研究所>有一个Nspire-CX版本!",
"B2B2B???",
"B2B2B2B存在吗?", "B2B2B2B存在吗?",
"MEGACMB!", "MEGACMB!",
"ALLSPIN!", "ALLSPIN!",
"O型回旋三清?", "O型回旋三清!",
"只用一个输入设备就可以游玩了",
"Miya:喵!", "Miya:喵!",
"225238922,哔哩哔哩 干杯~", "225238922 哔哩哔哩 干杯~",
"适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活", "适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活",
"合群了就会消失,但是消失不代表没有意义", "合群了就会消失,但是消失不代表没有意义",
"学会使用两个旋转键,三个更好", "学会使用两个旋转键,三个更好",
"更小的DAS和ARR拥有更高的操作上限", "更小的DAS和ARR拥有更高的操作上限(如果你还能控制得了的话)",
"注意到\"旋转\"到底对方块做了些什么吗?", "注意到\"旋转\"到底对方块做了些什么吗?",
"20G是一套全新的游戏规则", "20G本质是一套全新的游戏规则",
"不要在上课时玩游戏!", "不要在上课时玩游戏!",
"本游戏难度上限很高,做好心理准备", "本游戏难度上限很高,做好心理准备",
"方块可以不是个休闲游戏", "方块可以不是个休闲游戏",
"调到特殊的日期也不会发生什么的", "调到特殊的日期也不会发生什么的",
"[随机文本]", "3.1415926535897932384",
"2.7182818284590452353",
"Let-The-Bass-Kick!",
"使用love2d引擎制作",
"有疑问?先看设置有没有你想要的",
"有建议的话可以把信息反馈给作者~",
"不要按F8",
"秘密代码:626",
"CLASSIC SEXY RUSSIAN BLOCKS",
"LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI
}, },
stat={ stat={
"游戏运行次数:", "游戏运行次数:",
@@ -132,6 +163,8 @@ return{
"满贯数:", "满贯数:",
"全清数:", "全清数:",
"效率:", "效率:",
"多余操作:",
"最简操作率:",
}, },
help={ help={
"好像也没啥好帮助的吧?就当是关于了", "好像也没啥好帮助的吧?就当是关于了",
@@ -142,14 +175,25 @@ return{
"使用LOVE2D引擎", "使用LOVE2D引擎",
"作者:MrZ 邮箱:1046101471@qq.com", "作者:MrZ 邮箱:1046101471@qq.com",
"程序:MrZ 美术:MrZ 音乐:MrZ 音效:MrZ 语音:Miya", "程序:MrZ 美术:MrZ 音乐:MrZ 音效:MrZ 语音:Miya",
"使用工具:VScode,GFIE,Beepbox,Goldwave", "特别感谢:Farter,Flyz,196,Teatube,T830,[所有测试人员]和 你!",
"特别感谢:Farter,Teatube,196,Flyz,T830,[所有测试人员]和 你!",
"错误或者建议请附带相关信息发送到作者邮箱~", "错误或者建议请附带相关信息发送到作者邮箱~",
}, },
used=[[
使用工具:
Beepbox
GFIE
Goldwave
使用库:
Cold_Clear[MinusKelvin]
simple-love-lights[dylhunn]
]],
support="支持作者", support="支持作者",
group="官方QQ群", group="官方QQ群",
ButtonText={ warning="禁 止 私 自 传 播",
WidgetText={
main={ main={
lang="文-Lang",
qplay="快速开始",
play="开始", play="开始",
setting="设置", setting="设置",
music="音乐室", music="音乐室",
@@ -164,13 +208,14 @@ return{
right="", right="",
start="开始", start="开始",
custom="自定义(C)", custom="自定义(C)",
back="返回", back=BK,
}, },
music={ music={
bgm="BGM",
up="", up="",
play="播放", play="播放",
down="", down="",
back="返回", back=BK,
}, },
custom={ custom={
up="", up="",
@@ -180,81 +225,123 @@ return{
start1="消除开始", start1="消除开始",
start2="拼图开始", start2="拼图开始",
draw="画图(D)", draw="画图(D)",
set1="40行", set1="40行(1)",
set2="1v1", set2="1v1(2)",
set3="无尽", set3="无尽(3)",
set4="隐形", set4="隐形(4)",
set5="极限", set5="极限(5)",
back="返回", back=BK,
}, },
draw={ draw={
any="不定", any="不定",
block1="", block1="Z",
block2="", block2="S",
block3="", block3="L",
block4="", block4="J",
block5="", block5="T",
block6="", block6="O",
block7="", block7="I",
gb1="", gb1="",
gb2="", gb2="",
gb3="", gb3="",
gb4="", gb4="",
gb5="", gb5="",
space="×", space="×",
clear="", clear="",
back="返回", back=BK,
}, },
play={ play={
pause="暂停", pause="暂停",
}, },
pause={ pause={
resume="继续", resume= "继续",
quit="退出", restart="重新开始",
setting="设置",
quit= "退出",
}, },
setting={
ghost=function()return setting.ghost and"阴影:开"or"阴影:关"end, setting_game={
center=function()return setting.center and"旋转中心:开"or"旋转中心:关"end, graphic="←画面设置",
grid=function()return setting.grid and"网格:开"or"网格:关"end, sound="声音设置→",
swap=function()return setting.swap and"目标选择:组合键"or"目标选择:循环"end,
fxs=function()return setting.fxs and"特效:开"or"特效:关"end,
bg=function()return setting.bg and"背景:开"or"背景:关"end,
dasD="-",dasU="+", dasD="-",dasU="+",
arrD="-",arrU="+", arrD="-",arrU="+",
sddasD="-",sddasU="+", sddasD="-",sddasU="+",
sdarrD="-",sdarrU="+", sdarrD="-",sdarrU="+",
ctrl="控制设置", quickR="快速重新开始",
touch="触摸设置", swap="组合键切换攻击模式",
lang=function()return langName[setting.lang]end, fine="极简操作提示音",
sfx=function()return setting.sfx and"音效:开"or"音效:关"end, ctrl="键位设置",
bgm=function()return setting.bgm and"音乐:开"or"音乐:关"end, touch="触屏设置",
vib=function()return "震动:"..setting.vib end, back=BK,
voc=function()return setting.voc and"语音:开"or"语音:关"end,
fullscreen=function()return setting.fullscreen and"全屏:开"or"全屏:关"end,
bgblock=function()return setting.bgblock and"背景动画:开"or"背景动画:关"end,
frame=function()return"绘制帧:"..setting.frameMul.."%"end,
skin="切换方块皮肤",
back="保存&返回",
}, },
setting2={ setting_graphic={
back="返回", sound="←声音设置",
game="游戏设置→",
ghost="阴影",
grid="网格",
center="旋转中心",
skin="皮肤",
bg="背景",
bgblock="背景动画",
smo="平滑下落",
dropFX="下落特效等级",
shakeFX="晃动特效等级",
atkFX="攻击特效等级",
fullscreen="全屏",
frame="绘制帧率",
back=BK,
}, },
setting3={ setting_sound={
back="返回", game="←游戏设置",
hide=function()return setting.virtualkeySwitch and"隐藏虚拟按键"or"显示虚拟按键"end, graphic="画面设置→",
sfx="音效",
bgm="音乐",
vib="震动",
voc="语音",
back=BK,
},
setting_key={
back=BK,
},
setting_touch={
hide="显示虚拟按键",
track="按键自动跟踪",
tkset="跟踪设置",
default="默认组合", default="默认组合",
snap=function()return text.snapLevelName[snapLevel]end, snap=function()return text.snapLevelName[snapLevel]end,
alpha=function()return percent0to5[setting.virtualkeyAlpha]end, alpha=function()return setting.VKAlpha.."0%"end,
icon="图标", icon="图标",
size="大小", size="大小",
toggle="开关",
back=BK,
},
setting_touchSwitch={
b1= actName[1],b2=actName[2],b3=actName[3],b4=actName[4],
b5= actName[5],b6=actName[6],b7=actName[7],b8=actName[8],
b9= actName[9],b10=actName[10],b11=actName[11],b12=actName[12],
b13=actName[13],b14=actName[14],b15=actName[15],b16=actName[16],
b17=actName[17],b18=actName[18],b19=actName[19],b20=actName[20],
norm="标准",
pro="专业",
back=BK,
},
setting_trackSetting={
VKDodge="自动避让",
back=BK,
}, },
help={ help={
back="返回", his="历史",
qq="作者QQ", qq="作者QQ",
back=BK,
},
history={
prev="",
next="",
back=BK,
}, },
stat={ stat={
back="返回",
path="打开存储目录", path="打开存储目录",
back=BK,
}, },
}, },
} }

View File

@@ -1,3 +1,11 @@
local BK="Back"
local actName={
"Move Left:","Move Right:",
"Rotate Right:","Rotate Left:","Rotate Flip:",
"Hard Drop:","Soft Drop:","Hold:","Function:","Restart:",
"Instant Left:","Instant Right:","Ins Down:","Down 1:","Down 4:","Down 10:",
"Left Drop:","Right Drop:","Left INS:","Right INS:",
}
return{ return{
atkModeName={"Random","Badges","K.O.s","Counters"}, atkModeName={"Random","Badges","K.O.s","Counters"},
royale_remain=function(n)return n.." Players Remain"end, royale_remain=function(n)return n.." Players Remain"end,
@@ -13,7 +21,10 @@ return{
PC="Perfect Clear", PC="Perfect Clear",
hold="Hold",next="Next", hold="Hold",next="Next",
stage={"STAGE 1","STAGE 2","STAGE 3","STAGE 4","STAGE 5",}, stage=function(n)return"STAGE "..n end,
great="Great!",
awesome="Awesome.",
continue="Continue.",
maxspeed="Max speed", maxspeed="Max speed",
speedup="Speed up", speedup="Speed up",
@@ -21,7 +32,7 @@ return{
lose="LOSE", lose="LOSE",
pause="PAUSE", pause="PAUSE",
finish="FINISH", finish="FINISH",
pauseTime="Pause time", pauseCount="Pause Count",
custom="Custom Game", custom="Custom Game",
customOption={ customOption={
@@ -40,7 +51,7 @@ return{
bgm="BGM:", bgm="BGM:",
}, },
customVal={ customVal={
drop={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,"","[20G]"}, drop={"[20G]",1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,""},
lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,""}, lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,""},
wait=nil, wait=nil,
fall=nil, fall=nil,
@@ -50,21 +61,28 @@ return{
visible={"normal","time","invisible","sudden"}, visible={"normal","time","invisible","sudden"},
target={10,20,40,100,200,500,1000,""}, target={10,20,40,100,200,500,1000,""},
freshLimit={0,8,15,""}, freshLimit={0,8,15,""},
opponent={"No CPU",1,2,3,4,5,6,7,8,9,10,11}, opponent={"No CPU","9S Lv1","9S Lv2","9S Lv3","9S Lv4","9S Lv5","CC Lv1","CC Lv2","CC Lv3","CC Lv4","CC Lv5","CC Lv6"},
}, },
softdropdas="Down DAS:", softdropdas="Down DAS:",
softdroparr="Down ARR:", softdroparr="Down ARR:",
snapLevelName={"Free pos","Snap-10","Snap-20","Snap-40","Snap-60","Snap-80"}, snapLevelName={"Free pos","Snap-10","Snap-20","Snap-40","Snap-60","Snap-80"},
keyboard="Keyboard",joystick="Joystick", keyboard="Keyboard",joystick="Joystick",
space="Space",enter="Enter", space="Space",enter="Enter",
setting2Help="Arrowkey to select/change slot,Enter to change,Esc back", ctrlSetHelp="Arrowkey to select/change slot,Enter to change,Esc back",
setting_game="Game setting",
setting_graphic="Graphic setting",
setting_sound="Sound setting",
musicRoom="Music Room", musicRoom="Music Room",
nowPlaying="Now Playing:", nowPlaying="Now Playing:",
VKTchW="Touch weight",
VKOrgW="Origion weight",
VKCurW="CurPos weight",
actName={"Move Left:","Move Right:","Rotate Right:","Rotate Left:","Rotate Flip:","Hard Drop:","Soft Drop:","Hold:","Function:","Restart:","Instant Left:","Instant Right:","Ins Down:"}, actName=actName,
modeName={ modeName={
[0]="Custom", [0]="Custom",
"Sprint","Marathon","Master","Classic","Zen","Infinite","1v1","TSD-only","Blind","Dig","Survivor","Tech", "Sprint","Marathon","Master","Classic","Zen","Infinite","1v1","Round","TSD-only","Blind",
"Dig","Survivor","Defender","Attacker","Tech",
"C4W Train","PC Train","PC Challenge","Techmino49","Techmino99","Drought","Hotseat", "C4W Train","PC Train","PC Challenge","Techmino49","Techmino99","Drought","Hotseat",
}, },
modeInfo={ modeInfo={
@@ -75,10 +93,13 @@ return{
zen="Clear 200 Lines without gravity", zen="Clear 200 Lines without gravity",
infinite="Infinite game,infinite happiness", infinite="Infinite game,infinite happiness",
solo="Beat AI", solo="Beat AI",
round="Chess?",
tsd="Make more T-spin-doubles", tsd="Make more T-spin-doubles",
blind="Invisible board", blind="Invisible board",
dig="Downstack!", dig="Downstack!",
survivor="Hand them!", survivor="Survive Longer!",
defender="Hand them!",
attacker="Attacking better then defending",
tech="Don't do normal clear", tech="Don't do normal clear",
c4wtrain="Infinite combo", c4wtrain="Infinite combo",
pctrain="Let's learn some PCs", pctrain="Let's learn some PCs",
@@ -92,27 +113,36 @@ return{
load={"Loading VOICE","Loading BGM","Loading SFX","Finished",}, load={"Loading VOICE","Loading BGM","Loading SFX","Finished",},
tips={ tips={
"Not animation,real loading!", "Not animation,real loading!",
"The WHOLE game is made by MrZ!",
"Back to Back 10 combo Techrash PC!", "Back to Back 10 combo Techrash PC!",
"Techmino has a Nspire-CX edition!", "Techmino has a Nspire-CX edition!",
"B2B2B???",
"Is B2B2B2B possible?", "Is B2B2B2B possible?",
"MEGACMB!", "MEGACMB!",
"ALLSPIN!", "ALLSPIN!",
"O spin triple?", "O spin triple!",
"You can play with any input device!",
"Miya:Nya!", "Miya:Nya!",
"225238922,Bilibili cheers!", "225238922 Bilibili cheers!",
"Playing too much = taking drugs", "Playing too much = taking drugs",
"Disappearing doesn't mean useless", "Disappearing doesn't mean useless",
"Try to use two rotate button,three better", "Try to use two rotate button,three better",
"Small DAS&ARR can make you faster,if you can adapt to it", "Small DAS&ARR can make you faster,if you can control block correctly",
"Have you noticed what does \"rotating\" do to block?", "Have you noticed what does \"rotating\" do to block?",
"20G is a brand new game rule", "20G actually is a brand new game rule",
"Do not play game in class!", "Do not play game in class!",
"This game can be very hard,be mentally perpared", "This game can be very hard,be mentally perpared",
"This in not a casual game", "This in not a casual game",
"Nothing will happen when some special day come", "Nothing will happen when some special day come",
"[random text]", "3.1415926535897932384",
"2.7182818284590452353",
"Let-The-Bass-Kick!",
"Powered by love2d",
"Find out what's in the setting!",
"Any suggestions to author!",
"DO NOT PRESS F8",
"Secret code:626",
"Techmino=Technique+Tetromino",
"CLASSIC SEXY RUSSIAN BLOCKS",
"LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI
}, },
stat={ stat={
"Games run:", "Games run:",
@@ -122,7 +152,7 @@ return{
"Rotate:", "Rotate:",
"Hold:", "Hold:",
"Block used:", "Block used:",
"Rows cleared:", "Lines cleared:",
"Attack:", "Attack:",
"Sent:", "Sent:",
"Receive:", "Receive:",
@@ -132,6 +162,8 @@ return{
"B2B:", "B2B:",
"PC:", "PC:",
"Efficiency:", "Efficiency:",
"Finesse error:",
"Finesse rate:",
}, },
help={ help={
"I don't think you need \"help\".", "I don't think you need \"help\".",
@@ -141,15 +173,26 @@ return{
"", "",
"Powered by LOVE2D", "Powered by LOVE2D",
"Author:MrZ E-mail:1046101471@qq.com", "Author:MrZ E-mail:1046101471@qq.com",
"Programe:MrZ Art:MrZ Music:MrZ SFX:MrZ VOICE:Miya", "Program:MrZ Art:MrZ Music:MrZ SFX:MrZ VOICE:Miya",
"Tool used:VScode,GFIE,Beepbox,Goldwave", "Special thanks:Farter,Flyz,196,Teatube,T830,[all test staff] and YOU!",
"Special thanks:Farter,Teatube,196,Flyz,T830,[all test staff] and YOU!",
"Any bugs/suggestions to my E-mail.", "Any bugs/suggestions to my E-mail.",
}, },
used=[[
Tool used:
Beepbox
GFIE
Goldwave
Lib used:
Cold_Clear[MinusKelvin]
simple-love-lights[dylhunn]
]],
support="Support Author", support="Support Author",
group="Official QQ Group", group="Official QQ Group",
ButtonText={ warning="DO NOT DISTRIBUTE",
WidgetText={
main={ main={
lang="文-Lang",
qplay="Qplay",
play="Play", play="Play",
setting="Settings", setting="Settings",
music="Music room", music="Music room",
@@ -164,13 +207,14 @@ return{
right="", right="",
start="Start", start="Start",
custom="Custom(C)", custom="Custom(C)",
back="Back", back=BK,
}, },
music={ music={
bgm="BGM",
up="", up="",
play="Play", play="Play",
down="", down="",
back="Back", back=BK,
}, },
custom={ custom={
up="", up="",
@@ -180,81 +224,122 @@ return{
start1="Clear Start", start1="Clear Start",
start2="Puzzle Start", start2="Puzzle Start",
draw="Draw(D)", draw="Draw(D)",
set1="40L", set1="40L(1)",
set2="1v1", set2="1v1(2)",
set3="infinite", set3="infinite(3)",
set4="blind", set4="blind(4)",
set5="classic", set5="master(5)",
back="Back", back=BK,
}, },
draw={ draw={
any="ANY", any="ANY",
block1="", block1="Z",
block2="", block2="S",
block3="", block3="L",
block4="", block4="J",
block5="", block5="T",
block6="", block6="O",
block7="", block7="I",
gb1="", gb1="",
gb2="", gb2="",
gb3="", gb3="",
gb4="", gb4="",
gb5="", gb5="",
space="×", space="×",
clear="CLEAR", clear="Clear",
back="Back", back=BK,
}, },
play={ play={
pause="Pause", pause="Pause",
}, },
pause={ pause={
resume="Resume", resume="Resume",
restart="Restart",
setting="Setting",
quit="Quit", quit="Quit",
}, },
setting={ setting_game={
ghost=function()return setting.ghost and"Ghost:ON"or"Ghost:OFF"end, graphic="←Graphic",
center=function()return setting.center and"Center:ON"or"Center:OFF"end, sound="Sound→",
grid=function()return setting.grid and"Grid:ON"or"Grid:OFF"end,
swap=function()return setting.swap and"Swap:comboKey"or"Swap:loop"end,
fxs=function()return setting.fxs and"FXs:ON"or"FXs:OFF"end,
bg=function()return setting.bg and"BG:ON"or"BG:OFF"end,
dasD="-",dasU="+", dasD="-",dasU="+",
arrD="-",arrU="+", arrD="-",arrU="+",
sddasD="-",sddasU="+", sddasD="-",sddasU="+",
sdarrD="-",sdarrU="+", sdarrD="-",sdarrU="+",
ctrl="Control settings", quickR="Quick restart",
touch="Touch settings", swap="Combo key to change ATK mode",
lang=function()return langName[setting.lang]end, fine="Finesse error SFX",
sfx=function()return setting.sfx and"SFX:ON"or"SFX:OFF"end, ctrl="Key Setting",
bgm=function()return setting.bgm and"BGM:ON"or"BGM:OFF"end, touch="Touch Setting",
voc=function()return setting.voc and"VOC:ON"or"VOC:OFF"end, back=BK,
vib=function()return "VIB:"..setting.vib end,
fullscreen=function()return setting.fullscreen and"Fullscreen:ON"or"Fullscreen:OFF"end,
bgblock=function()return setting.bgblock and"BG animation:ON"or"BG animation:OFF"end,
frame=function()return"FrameDraw:"..setting.frameMul.."%"end,
skin="Change Block Skin",
back="Save&Back",
}, },
setting2={ setting_graphic={
back="Back", sound="←Sound",
game="Game→",
ghost="Ghost",
grid="Grid",
center="Center",
skin="Skin",
bg="Background",
bgblock="BG animation",
smo="Smoooth drop",
dropFX="Drop FX level",
shakeFX="Shake FX level",
atkFX="ATK FX level",
fullscreen="Fullscreen",
frame="draw FPS",
back=BK,
}, },
setting3={ setting_sound={
back="Back", game="←Game",
hide=function()return setting.virtualkeySwitch and"Hide Virtual Key"or"Show Virtual Key"end, graphic="Graphic→",
sfx="SFX",
bgm="BGM",
vib="VIB",
voc="VOC",
back=BK,
},
setting_key={
back=BK,
},
setting_touch={
hide="Show Virtual Key",
track="Auto track",
tkset="Track setting",
default="Defaults", default="Defaults",
snap=function()return text.snapLevelName[snapLevel]end, snap=function()return text.snapLevelName[snapLevel]end,
alpha=function()return percent0to5[setting.virtualkeyAlpha]end, alpha=function()return setting.VKAlpha.."0%"end,
icon="Icon", icon="Icon",
size="Size", size="Size",
toggle="Toggle",
back=BK,
},
setting_touchSwitch={
b1= actName[1],b2=actName[2],b3=actName[3],b4=actName[4],
b5= actName[5],b6=actName[6],b7=actName[7],b8=actName[8],
b9= actName[9],b10=actName[10],b11=actName[11],b12=actName[12],
b13=actName[13],b14=actName[14],b15=actName[15],b16=actName[16],
b17=actName[17],b18=actName[18],b19=actName[19],b20=actName[20],
norm="Normal",
pro="Professioanl",
back=BK,
},
setting_trackSetting={
VKDodge="Auto Dodge",
back=BK,
}, },
help={ help={
back="Back", his="History",
qq="Author's qq", qq="Author's qq",
back=BK,
},
history={
prev="",
next="",
back=BK,
}, },
stat={ stat={
back="Back",
path="Open Data Folder", path="Open Data Folder",
back=BK,
}, },
} }
} }

80
light.lua Normal file
View File

@@ -0,0 +1,80 @@
--LIGHT MODULE(Optimized by MrZ,Original on github/love2d community/simple-love-lights)
--Heavily based on mattdesl's libGDX implementation:
--https://github.com/mattdesl/lwjgl-basics/wiki/2D-Pixel-Perfect-Shadows
local gc=love.graphics
local C=gc.clear
local shadowMapShader=gc.newShader("shadowMapShader.cs")--Shader for caculating the 1D shadow map.
local lightRenderShader=gc.newShader("lightRenderShader.cs")--Shader for rendering blurred lights and shadows.
Lights={}--Lightsource objects
local Lights=Lights
--Private--
local function move(L,x,y)
L.x,L.y=x,y
end
local function setPow(L,pow)
L.size=pow
end
local function destroy(L)
L.blackCanvas:release()
L.shadowCanvas:release()
L.renderCanvas:release()
end
local function draw(L)
local r,g,b,a=love.graphics.getColor()
gc.setCanvas(L.blackCanvas)C()
gc.setCanvas(L.shadowCanvas)C()
gc.setCanvas(L.renderCanvas)C()
lightRenderShader:send("xresolution",L.size);
shadowMapShader:send("yresolution",L.size);
--初始化数据
local X=L.x-L.size*.5
local Y=L.y-L.size*.5
--整束光的左上角
gc.translate(-X,-Y)
L.blackCanvas:renderTo(L.blackFn)
gc.translate(X,Y)
--渲染遮光物
gc.setShader(shadowMapShader)
gc.setCanvas(L.shadowCanvas)
gc.draw(L.blackCanvas)
--根据遮光物渲染阴影画布
gc.setShader(lightRenderShader)
gc.setCanvas(L.renderCanvas)
gc.draw(L.shadowCanvas,0,0,0,1,L.size)
--根据阴影画布渲染光画布
gc.setShader()gc.setCanvas()gc.setBlendMode("add")
--准备渲染
gc.setColor(r,g,b,a)
gc.draw(L.renderCanvas,X,Y+L.size,0,1,-1)
--渲染到屏幕
gc.setBlendMode("alpha")
--复位
end
--Public--
function drawLight()
for i=1,#Lights do
Lights[i]:draw()
end
end
function clearLight(L)
for i=1,#Lights do
Lights[i]:destroy()
Lights[i]=nil
end
end
function addLight(x,y,R,F)
local id=#Lights+1
Lights[id]={
id=id,
x=x,y=y,size=R,
blackCanvas=gc.newCanvas(R,R),--遮挡物画布
shadowCanvas=gc.newCanvas(R,1),--1D视深画布
renderCanvas=gc.newCanvas(R,R),--灯光画布
blackFn=F,--遮挡物绘图函数
--方法
move=move,
setPow=setPow,
draw=draw,
destroy=destroy,
}
end

30
lightRenderShader.cs Normal file
View File

@@ -0,0 +1,30 @@
#define PI 3.14
extern float xresolution;
//从1D距离map采样
float samp(vec2 coord,float r,Image u_texture){
return step(r,Texel(u_texture,coord).r);
}
vec4 effect(vec4 color,Image texture,vec2 texture_coords,vec2 screen_coords){
//直角转极坐标用于采样1D材质的y总是0
vec2 norm=texture_coords.st*2.-1.;
float r=length(norm);
vec2 tc=vec2((atan(norm.y,norm.x)+PI)/(2.*PI),0.);
//根据离光源距离放大模糊系数,模拟影子淡出
float blur=(1./xresolution)*smoothstep(0.,1.,r);
//简易高斯模糊
float sum=
samp(vec2(tc.x-4.*blur,tc.y),r,texture)*.5
+samp(vec2(tc.x-3.*blur,tc.y),r,texture)*.9
+samp(vec2(tc.x-2.*blur,tc.y),r,texture)*.12
+samp(vec2(tc.x-1.*blur,tc.y),r,texture)*.15
+samp(tc,r,texture)*.16//The center tex coord,which gives us hard shadows.
+samp(vec2(tc.x+1.*blur,tc.y),r,texture)*.15
+samp(vec2(tc.x+2.*blur,tc.y),r,texture)*.12
+samp(vec2(tc.x+3.*blur,tc.y),r,texture)*.9
+samp(vec2(tc.x+4.*blur,tc.y),r,texture)*.5;
//sum值为亮度(0~1)
//乘上距离得到逐渐变淡的光线
return vec4(vec3(1.),sum*smoothstep(1.,.1,r));
}

583
list.lua
View File

@@ -1,8 +1,13 @@
local gc=love.graphics local mobile=system=="Android"or system=="iOS"
local tc,kb=love.touch,love.keyboard actName={
local sys=love.system "moveLeft","moveRight",
local fs=love.filesystem "rotRight","rotLeft","rotFlip",
actName={"moveLeft","moveRight","rotRight","rotLeft","rotFlip","hardDrop","softDrop","hold","func","restart","insLeft","insRight","insDown"} "hardDrop","softDrop",
"hold","func",
"restart",
"insLeft","insRight","insDown","down1","down4","down10",
"dropLeft","dropRight","addLeft","addRight",--Super contorl system
}
color={ color={
red={1,0,0}, red={1,0,0},
green={0,1,0}, green={0,1,0},
@@ -44,13 +49,16 @@ blockColor={
color.yellow, color.yellow,
color.cyan, color.cyan,
color.darkGreen, color.darkGreen,
color.darkGrey,
color.grey, color.grey,
color.lightGrey,
color.darkPurple, color.darkPurple,
color.darkRed, color.darkRed,
color.darkGreen, color.darkGreen,
} }
sfx={ sfx={
"welcome",
"error","error_long",
--Stereo sfxs
"button","swipe", "button","swipe",
"ready","start","win","fail","collect", "ready","start","win","fail","collect",
"move","rotate","rotatekick","hold", "move","rotate","rotatekick","hold",
@@ -62,6 +70,7 @@ sfx={
"spin_0","spin_1","spin_2","spin_3", "spin_0","spin_1","spin_2","spin_3",
"emit","blip_1","blip_2", "emit","blip_1","blip_2",
"perfectclear", "perfectclear",
--mono sfxs
} }
bgm={ bgm={
"blank", "blank",
@@ -77,16 +86,17 @@ bgm={
"secret8th", "secret8th",
"rockblock", "rockblock",
"8-bit happiness", "8-bit happiness",
"shining terminal",
"end", "end",
} }
voiceList={ voiceBank={}
voiceName={
"Z","S","L","J","T","O","I", "Z","S","L","J","T","O","I",
"single","double","triple","tts", "single","double","triple","tts",
"spin","spin_","mini","b2b","b3b","pc", "spin","spin_","mini","b2b","b3b","pc",
"win","lose","voc_nya","nya", "win","lose","voc_nya","nya",
} }
voiceBank={} voiceList={
voice={
Z={"Z_1","Z_2"}, Z={"Z_1","Z_2"},
S={"S_1","S_2"}, S={"S_1","S_2"},
J={"J_1","J_2"}, J={"J_1","J_2"},
@@ -118,12 +128,13 @@ musicID={
"push", "push",
"reason", "reason",
"infinite", "infinite",
"cruelty",
"final",
"secret7th", "secret7th",
"secret8th", "secret8th",
"shining terminal",
"rockblock", "rockblock",
"8-bit happiness", "8-bit happiness",
"cruelty",
"final",
"end", "end",
} }
customID={ customID={
@@ -137,7 +148,7 @@ customID={
"bg","bgm", "bg","bgm",
} }
customRange={ customRange={
drop={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,1e99,-1}, drop={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,1e99},
lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,1e99}, lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,1e99},
wait={0,1,2,3,4,5,6,7,8,10,15,20,30,60}, wait={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
fall={0,1,2,3,4,5,6,7,8,10,15,20,30,60}, fall={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
@@ -147,7 +158,7 @@ customRange={
visible={"show","time","fast","none"}, visible={"show","time","fast","none"},
target={10,20,40,100,200,500,1000,1e99}, target={10,20,40,100,200,500,1000,1e99},
freshLimit={0,8,15,1e99}, freshLimit={0,8,15,1e99},
opponent={0,60,30,20,15,10,7,5,4,3,2,1}, opponent={0,1,2,3,4,5,11,12,13,14,15,16},
bg={"none","game1","game2","game3","strap","rgb","glow","matrix"}, bg={"none","game1","game2","game3","strap","rgb","glow","matrix"},
bgm={"blank","way","race","newera","push","reason","infinite","secret7th","secret8th","rockblock"}, bgm={"blank","way","race","newera","push","reason","infinite","secret7th","secret8th","rockblock"},
} }
@@ -155,31 +166,34 @@ customRange={
RCPB={10,33,200,33,105,5,105,60} RCPB={10,33,200,33,105,5,105,60}
snapLevelValue={1,10,20,40,60,80} snapLevelValue={1,10,20,40,60,80}
up0to4={[0]="000%UP","025%UP","050%UP","075%UP","100%UP",} up0to4={[0]="000%UP","025%UP","050%UP","075%UP","100%UP",}
percent0to5={[0]="0%","20%","40%","60%","80%","100%",} sectionName={"M7","M8","M9","M","MK","MV","MO","MM","GM"}
modeID={ modeID={
[0]="custom", [0]="custom",
"sprint","marathon","master","classic","zen","infinite","solo","tsd","blind","dig","survivor","tech", "sprint","marathon","master","classic","zen","infinite","solo","round","tsd","blind",
"dig","survivor","defender","attacker","tech",
"c4wtrain","pctrain","pcchallenge","techmino49","techmino99","drought","hotseat", "c4wtrain","pctrain","pcchallenge","techmino49","techmino99","drought","hotseat",
} }
modeLevel={ modeLevel={
sprint={"10L","20L","40L","100L","400L","1000L"}, sprint={"10L","20L","40L","100L","400L","1000L"},
marathon={"EASY","NORMAL","HARD"}, marathon={"EASY","NORMAL","HARD"},
master={"LUNATIC","ULTIMATE"}, master={"LUNATIC","ULTIMATE","FINAL"},
classic={"CTWC"}, classic={"CTWC"},
zen={"NORMAL"}, zen={"NORMAL"},
infinite={"NORMAL","EXTRA"}, infinite={"NORMAL","EXTRA"},
solo={"EASY","NORMAL","HARD","LUNATIC"}, solo={"EASY","EASY+","NORMAL","NORMAL+","HARD","HARD+","LUNATIC","LUNATIC+","ULTIMATE"},
round={"EASY","NORMAL","HARD","LUNATIC","ULTIMATE"},
tsd={"NORMAL","HARD"}, tsd={"NORMAL","HARD"},
blind={"EASY","HARD","HARD+","LUNATIC","ULTIMATE","GM"}, blind={"EASY","HARD","HARD+","LUNATIC","ULTIMATE","GM"},
dig={"NORMAL","LUNATIC"}, dig={"NORMAL","LUNATIC"},
survivor={"EASY","NORMAL","HARD","LUNATIC","ULTIMATE"}, survivor={"EASY","NORMAL","HARD","LUNATIC","ULTIMATE"},
tech={"NORMAL","NORMAL+","HARD","LUNATIC","ULTIMATE"}, defender={"NORMAL","LUNATIC"},
attacker={"HARD","ULTIMATE"},
tech={"NORMAL","NORMAL+","HARD","HARD+","LUNATIC","LUNATIC+","ULTIMATE","ULTIMATE+",},
c4wtrain={"NORMAL","LUNATIC"}, c4wtrain={"NORMAL","LUNATIC"},
pctrain={"NORMAL","EXTRA"}, pctrain={"NORMAL","EXTRA"},
pcchallenge={"NORMAL","HARD","LUNATIC"}, pcchallenge={"NORMAL","HARD","LUNATIC"},
techmino49={"EASY","NORMAL","HARD","LUNATIC","ULTIMATE"}, techmino49={"EASY","HARD","ULTIMATE"},
techmino99={"EASY","NORMAL","HARD","LUNATIC","ULTIMATE"}, techmino99={"EASY","HARD","ULTIMATE"},
drought={"NORMAL","MESS"}, drought={"NORMAL","MESS"},
hotseat={"2P","3P","4P",}, hotseat={"2P","3P","4P",},
custom={"Normal","Puzzle"}, custom={"Normal","Puzzle"},
@@ -199,72 +213,83 @@ for i=1,7 do blocks[i+7]=blocks[i]end
local virtualkeySet={ local virtualkeySet={
{ {
{80,720-200,6400,80},--moveLeft {1, 80, 720-200, 80},--moveLeft
{320,720-200,6400,80},--moveRight {2, 320, 720-200, 80},--moveRight
{1280-80,720-200,6400,80},--rotRight {3, 1280-80, 720-200, 80},--rotRight
{1280-200,720-80,6400,80},--rotLeft {4, 1280-200, 720-80, 80},--rotLeft
{1280-200,720-320,6400,80},--rotFlip {5, 1280-200, 720-320, 80},--rotFlip
{200,720-320,6400,80},--hardDrop {6, 200, 720-320, 80},--hardDrop
{200,720-80,6400,80},--softDrop {7, 200, 720-80, 80},--softDrop
{1280-320,720-200,6400,80},--hold {8, 1280-320, 720-200, 80},--hold
{1280-80,280,6400,80},--func {9, 1280-80, 280, 80},--func
{80,280,6400,80},--restart {10,80, 280, 80},--restart
},--Farter's set 3 },--Farter's set,thanks
{ {
{1280-320,720-200,6400,80},--moveLeft {1, 1280-320, 720-200, 80},--moveLeft
{1280-80,720-200,6400,80},--moveRight {2, 1280-80, 720-200, 80},--moveRight
{200,720-80,6400,80},--rotRight {3, 200, 720-80, 80},--rotRight
{80,720-200,6400,80},--rotLeft {4, 80, 720-200, 80},--rotLeft
{200,720-320,6400,80},--rotFlip {5, 200, 720-320, 80},--rotFlip
{1280-200,720-320,6400,80},--hardDrop {6, 1280-200, 720-320, 80},--hardDrop
{1280-200,720-80,6400,80},--softDrop {7, 1280-200, 720-80, 80},--softDrop
{320,720-200,6400,80},--hold {8, 320, 720-200, 80},--hold
{80,280,6400,80},--func {9, 80, 280, 80},--func
{1280-80,280,6400,80},--restart {10,1280-80, 280, 80},--restart
},--Mirrored farter's set 3
},--Mirrored farter's set,sknaht
{ {
{80,720-80,6400,80},--moveLeft {1, 80, 720-80, 80},--moveLeft
{240,720-80,6400,80},--moveRight {2, 240, 720-80, 80},--moveRight
{1280-240,720-80,6400,80},--rotRight {3, 1280-240, 720-80, 80},--rotRight
{1280-400,720-80,6400,80},--rotLeft {4, 1280-400, 720-80, 80},--rotLeft
{1280-240,720-240,6400,80},--rotFlip {5, 1280-240, 720-240, 80},--rotFlip
{1280-80,720-80,6400,80},--hardDrop {6, 1280-80, 720-80, 80},--hardDrop
{1280-80,720-240,6400,80},--softDrop {7, 1280-80, 720-240, 80},--softDrop
{1280-80,720-400,6400,80},--hold {8, 1280-80, 720-400, 80},--hold
{80,360,6400,80},--func {9, 80, 360, 80},--func
{80,80,6400,80},--restart {10,80, 80, 80},--restart
},--Author's set },--Author's set,not recommend
{ {
{1280-400,720-80,6400,80},--moveLeft {1, 1280-400, 720-80, 80},--moveLeft
{1280-80,720-80,6400,80},--moveRight {2, 1280-80, 720-80, 80},--moveRight
{240,720-80,6400,80},--rotRight {3, 240, 720-80, 80},--rotRight
{80,720-80,6400,80},--rotLeft {4, 80, 720-80, 80},--rotLeft
{240,720-240,6400,80},--rotFlip {5, 240, 720-240, 80},--rotFlip
{1280-240,720-240,6400,80},--hardDrop {6, 1280-240, 720-240, 80},--hardDrop
{1280-240,720-80,6400,80},--softDrop {7, 1280-240, 720-80, 80},--softDrop
{1280-80,720-240,6400,80},--hold {8, 1280-80, 720-240, 80},--hold
{80,720-240,6400,80},--func {9, 80, 720-240, 80},--func
{80,320,6400,80},--restart {10,80, 320, 80},--restart
},--Keyboard set },--Keyboard set
{ {
{1200-370,40,1600,40},--moveLeft {10,70, 50,27},--restart
{1200-280,40,1600,40},--moveRight {9, 130, 50,27},--func
{1200-530,40,1600,40},--rotRight {4, 190, 50,27},--rotLeft
{1200-610,40,1600,40},--rotLeft {3, 250, 50,27},--rotRight
{1200-450,40,1600,40},--rotFlip {5, 310, 50,27},--rotFlip
{1200-50,40,1600,40},--hardDrop {1, 370, 50,27},--moveLeft
{1200-130,40,1600,40},--softDrop {2, 430, 50,27},--moveRight
{1200-210,40,1600,40},--hold {8, 490, 50,27},--hold
{1200-690,40,1600,40},--func {7, 550, 50,27},--softDrop1
{1200-770,40,1600,40},--restart {6, 610, 50,27},--hardDrop
},--PC key feedback {11,670, 50,27},--insLeft
{12,730, 50,27},--insRight
{13,790, 50,27},--insDown
{14,850, 50,27},--down1
{15,910, 50,27},--down4
{16,970, 50,27},--down10
{17,1030, 50,27},--dropLeft
{18,1090, 50,27},--dropRight
{19,1150, 50,27},--addLeft
{20,1210, 50,27},--addRight
},--PC key feedback(top&in a row)
} }
local customSet={ local customSet={
{20,20,1,1,7,1,1,1,3,4,1,3,3}, {20,20,1,1,7,1,1,1,3,4,1,2,3},
{18,20,1,1,7,1,1,1,8,3,8,3,3}, {18,20,1,1,7,1,1,1,8,3,8,3,3},
{22,22,1,1,7,3,1,3,8,4,1,8,7}, {22,22,1,1,7,3,1,1,8,4,1,7,7},
{20,20,1,1,7,1,1,3,8,3,1,7,8}, {20,20,1,1,7,1,1,3,8,3,1,7,8},
{23,11,8,11,4,1,2,1,8,3,1,4,9}, {1,11,8,11,4,1,2,1,8,3,1,4,9},
} }
local function useDefaultSet(n) local function useDefaultSet(n)
for i=1,#customSet[n]do for i=1,#customSet[n]do
@@ -273,185 +298,267 @@ local function useDefaultSet(n)
curBG=customRange.bg[customSel[12]] curBG=customRange.bg[customSel[12]]
BGM(customRange.bgm[customSel[13]]) BGM(customRange.bgm[customSel[13]])
end end
Buttons={ local function VKAdisp(n)
load={}, return function()
intro={}, return VK_org[n].ava
end
end
local function VKAcode(n)
return function()
VK_org[n].ava=not VK_org[n].ava
end
end
Widget={
load={},intro={},quit={},
main={ main={
play= {x=380,y=300,w=240, h=240,rgb=color.red, f=70,code=function()gotoScene("mode")end,down="stat",right="setting"}, play= newButton(150,280,200,160,color.red, 60,function()scene.push()scene.swapTo("mode")end, nil,"setting"),
setting={x=640,y=300,w=240, h=240,rgb=color.lightBlue, f=55,code=function()gotoScene("setting")end,down="stat",left="play",right="music"}, setting=newButton(370,280,200,160,color.lightBlue, 50,function()scene.push()scene.swapTo("setting_game")end, nil,"music"),
music= {x=900,y=300,w=240, h=240,rgb=color.lightCyan, f=42,code=function()gotoScene("music")end,down="help",left="setting",right="quit"}, music= newButton(590,280,200,160,color.lightPurple,37,function()scene.push()scene.swapTo("music")end, nil,"help"),
stat= {x=640,y=560,w=240, h=240,rgb=color.cyan, f=55,code=function()gotoScene("stat")end,up="setting",left="play",right="help"}, help= newButton(150,460,200,160,color.yellow, 55,function()scene.push()scene.swapTo("help")end, nil,"stat"),
help= {x=900,y=560,w=240, h=240,rgb=color.yellow, f=55,code=function()gotoScene("help")end,up="music",left="stat",right="quit"}, stat= newButton(370,460,200,160,color.cyan, 48,function()scene.push()scene.swapTo("stat")end, nil,"qplay"),
quit= {x=1180,y=620,w=120,h=120,rgb=color.lightGrey, f=50,code=function()gotoScene("quit")end,up="setting",left="help"}, qplay= newButton(540,415,100,70,color.lightGreen, 28,function()scene.push()loadGame(modeSel,levelSel)end, nil,"lang"),
}, lang= newButton(590,505,200,70,color.lightRed, 50,function()
mode={
up= {x=1000,y=210,w=200,h=140, rgb=color.white, f=80, code=function()love.keypressed("up")end, hide=function()return modeSel==1 end,},
down= {x=1000,y=430,w=200,h=140, rgb=color.white, f=80, code=function()love.keypressed("down")end, hide=function()return modeSel==#modeID end,},
left= {x=190, y=160,w=100,h=80, rgb=color.white, code=function()love.keypressed("left")end, hide=function()return levelSel==1 end,},
right= {x=350, y=160,w=100,h=80, rgb=color.white, code=function()love.keypressed("right")end,hide=function()return levelSel==#modeLevel[modeID[modeSel]]end,},
start= {x=1000,y=600,w=250,h=100, rgb=color.green, f=50, code=function()
loadGame(modeSel,levelSel)end},
custom= {x=275, y=420,w=200,h=90, rgb=color.yellow, code=function()gotoScene("custom")end},
back= {x=640, y=630,w=230,h=90, rgb=color.white, f=45, code=back},
},
music={
up= {x=1100,y=200,w=120,h=120, rgb=color.white,f=40,code=function()sel=(sel-2)%#musicID+1 end},
play= {x=1100,y=340,w=120,h=120, rgb=color.white,f=40,code=function()BGM(musicID[sel])end},
down= {x=1100,y=480,w=120,h=120, rgb=color.white,f=50,code=function()sel=sel%#musicID+1 end},
back= {x=640, y=630,w=230,h=90, rgb=color.white,f=45,code=back},
},
custom={
up= {x=1000,y=220, w=100,h=100, rgb=color.white,f=50, code=function()optSel=(optSel-2)%#customID+1 end},
down= {x=1000,y=460, w=100,h=100, rgb=color.white,f=50, code=function()optSel=optSel%#customID+1 end},
left= {x=880, y=340, w=100,h=100, rgb=color.white,f=50, code=function()customSel[optSel]=(customSel[optSel]-2)%#customRange[customID[optSel]]+1 end},
right= {x=1120,y=340, w=100,h=100, rgb=color.white,f=50, code=function()customSel[optSel]=customSel[optSel]%#customRange[customID[optSel]]+1 end},
start1= {x=880, y=580, w=220,h=70, rgb=color.green, code=function()loadGame(0,1)end},
start2= {x=1120,y=580, w=220,h=70, rgb=color.lightPurple, code=function()loadGame(0,2)end},
draw= {x=1000,y=90, w=190,h=85, rgb=color.cyan, code=function()gotoScene("draw")end},
set1= {x=640, y=160, w=240,h=75, rgb=color.lightRed, code=function()useDefaultSet(1)end},
set2= {x=640, y=250, w=240,h=75, rgb=color.lightRed, code=function()useDefaultSet(2)end},
set3= {x=640, y=340, w=240,h=75, rgb=color.lightRed, code=function()useDefaultSet(3)end},
set4= {x=640, y=430, w=240,h=75, rgb=color.lightRed, code=function()useDefaultSet(4)end},
set5= {x=640, y=520, w=240,h=75, rgb=color.lightRed, code=function()useDefaultSet(5)end},
back= {x=640, y=630, w=180,h=60, rgb=color.white, code=back},
},
draw={
any= {x=700, y=80,w=120,h=120, f=45, rgb=color.lightGrey,code=function()pen=-1 end},
block1= {x=840, y=80,w=120,h=120, f=65, rgb=color.red, code=function()pen=1 end},
block2= {x=980, y=80,w=120,h=120, f=65, rgb=color.green, code=function()pen=2 end},
block3= {x=1120,y=80,w=120,h=120, f=65, rgb=color.orange, code=function()pen=3 end},
block4= {x=840, y=220,w=120,h=120, f=65, rgb=color.blue, code=function()pen=4 end},
block5= {x=980, y=220,w=120,h=120, f=65, rgb=color.magenta, code=function()pen=5 end},
block6= {x=1120,y=220,w=120,h=120, f=65, rgb=color.yellow, code=function()pen=6 end},
block7= {x=840, y=360,w=120,h=120, f=65, rgb=color.cyan, code=function()pen=7 end},
gb1= {x=980, y=360,w=120,h=120, f=65, rgb=color.darkGrey, code=function()pen=9 end},
gb2= {x=1120,y=360,w=120,h=120, f=65, rgb=color.grey, code=function()pen=10 end},
gb3= {x=840, y=500,w=120,h=120, f=65, rgb=color.darkPurple,code=function()pen=11 end},
gb4= {x=980, y=500,w=120,h=120, f=65, rgb=color.darkRed, code=function()pen=12 end},
gb5= {x=1120,y=500,w=120,h=120, f=65, rgb=color.darkGreen,code=function()pen=13 end},
space= {x=840, y=640,w=120,h=120, f=70, rgb=color.grey, code=function()pen=0 end},
clear= {x=1120,y=640,w=120,h=120, f=45, rgb=color.white, code=function()
if clearSureTime>0 then
for y=1,20 do for x=1,10 do preField[y][x]=0 end end
clearSureTime=0
else
clearSureTime=50
end
end},
back= {x=1235,y=45,w=80,h=80, f=35, rgb=color.white, code=back},
},
play={
pause={x=1235,y=45,w=80,h=80,rgb=color.white,f=30,code=pauseGame},
},
pause={
resume= {x=640,y=400,w=240,h=100, rgb=color.white,f=50,code=resumeGame},
quit= {x=640,y=550,w=240,h=100, rgb=color.white,f=50,code=back},
},
setting={--Normal setting
ghost= {x=290, y=90, w=210, h=60, rgb=color.white,code=function()setting.ghost=not setting.ghost end,down="grid",right="center"},
center= {x=505, y=90, w=210, h=60, rgb=color.white,code=function()setting.center=not setting.center end,down="swap",left="ghost",right="sfx"},
grid= {x=290, y=160, w=210, h=60, rgb=color.white,code=function()setting.grid=not setting.grid end,up="ghost",down="fxs",right="swap"},
swap= {x=505, y=160, w=210, h=60,f=28, rgb=color.white,code=function()setting.swap=not setting.swap end,up="center",down="bg",left="grid",right="vib"},
fxs= {x=290, y=230, w=210, h=60, rgb=color.white,code=function()setting.fxs=not setting.fxs end,up="grid",down="dasU",right="bg"},
bg= {x=505, y=230, w=210, h=60, rgb=color.white,code=function()setting.bg=not setting.bg end,up="swap",down="arrD",right="fullscreen"},
dasD= {x=210, y=300, w=50, h=50, rgb=color.white,code=function()setting.das=(setting.das-1)%31 end,up="fxs",down="sddasD",right="dasU"},
dasU= {x=370, y=300, w=50, h=50, rgb=color.white,code=function()setting.das=(setting.das+1)%31 end,up="fxs",down="sddasU",left="dasD",right="arrD"},
arrD= {x=425, y=300, w=50, h=50, rgb=color.white,code=function()setting.arr=(setting.arr-1)%16 end,up="bg",down="sdarrD",left="dasU",right="arrU"},
arrU= {x=585, y=300, w=50, h=50, rgb=color.white,code=function()setting.arr=(setting.arr+1)%16 end,up="bg",down="sdarrU",left="arrD",right="bgblock"},--3~6
sddasD= {x=210, y=370, w=50, h=50, rgb=color.white,code=function()setting.sddas=(setting.sddas-1)%11 end,up="dasD",down="ctrl",right="sddasU"},
sddasU= {x=370, y=370, w=50, h=50, rgb=color.white,code=function()setting.sddas=(setting.sddas+1)%11 end,up="dasU",down="ctrl",left="sddasD",right="sdarrD"},
sdarrD= {x=425, y=370, w=50, h=50, rgb=color.white,code=function()setting.sdarr=(setting.sdarr-1)%4 end,up="arrD",down="ctrl",left="sddasU",right="sdarrU"},
sdarrU= {x=585, y=370, w=50, h=50, rgb=color.white,code=function()setting.sdarr=(setting.sdarr+1)%4 end,up="arrU",down="ctrl",left="sdarrD",right="frame"},
ctrl= {x=340,y=440, w=310,h=60,rgb=color.green, code=function()gotoScene("setting2")end,up="sddasU",down="touch",left="lang",right="skin"},
touch= {x=340,y=510, w=310,h=60,rgb=color.yellow,code=function()gotoScene("setting3")end,up="ctrl",down="back",right="lang"},
lang= {x=580,y=510, w=150,h=60,rgb=color.red, code=function()
setting.lang=setting.lang%#langName+1 setting.lang=setting.lang%#langName+1
swapLanguage(setting.lang) swapLanguage(setting.lang)
end,up="sdarrU",down="back",left="touch",right="skin"}, end,nil,"quit"),
quit= newButton(370,620,280,100,color.lightGrey, 60,function()scene.swapTo("quit")end, nil,"play"),
sfx= {x=760,y=90, w=160, h=60, rgb=color.white,code=function()setting.sfx=not setting.sfx end,down="vib",left="center",right="bgm"}, },
bgm= {x=940,y=90, w=160, h=60, rgb=color.white,code=function() mode={
BGM() up= newButton(1000, 210,200,140,color.white, 80,function()love.keypressed("up")end,function()return modeSel==1 end),
setting.bgm=not setting.bgm down= newButton(1000, 430,200,140,color.white, 80,function()love.keypressed("down")end,function()return modeSel==#modeID end),
BGM("blank") left= newButton(190, 160,100,80, color.white, 40,function()love.keypressed("left")end,function()return levelSel==1 end),
end,down="voc",left="sfx"}, right= newButton(350, 160,100,80, color.white, 40,function()love.keypressed("right")end,function()return levelSel==#modeLevel[modeID[modeSel]]end),
vib= {x=760,y=160, w=160, h=60,rgb=color.white, code=function() start= newButton(1000, 600,250,100,color.green, 50,function()scene.push()loadGame(modeSel,levelSel)end),
setting.vib=(setting.vib+1)%6 custom= newButton(275, 420,200,90, color.yellow, 40,function()scene.push()scene.swapTo("custom")end),
VIB(1) back= newButton(640, 630,230,90, color.white, 45,scene.back),
end,up="sfx",down="fullscreen",left="swap",right="voc"}, },
voc= {x=940,y=160, w=160, h=60,rgb=color.white, music={
hide=function()return true end, bgm= newSlider(760, 80,400,10,40,nil,function()return setting.bgm end,function(i)setting.bgm=i;BGM(bgmPlaying)end),
code=function() up= newButton(1100, 200,120,120,color.white,60,function()love.keypressed("up")end),
setting.voc=not setting.voc play= newButton(1100, 340,120,120,color.white,40,function()love.keypressed("space")end,function()return setting.bgm==0 end),
end,up="sfx",down="fullscreen",left="vib"}, down= newButton(1100, 480,120,120,color.white,60,function()love.keypressed("down")end),
fullscreen= {x=850,y=230, w=340,h=60,rgb=color.white, code=function() back= newButton(640, 630,230,90, color.white,45,scene.back),
},
custom={
up= newButton(1000, 220,100,100,color.white, 50,function()sel=(sel-2)%#customID+1 end),
down= newButton(1000, 460,100,100,color.white, 50,function()sel=sel%#customID+1 end),
left= newButton(880, 340,100,100,color.white, 50,function()love.keypressed("left")end),
right= newButton(1120, 340,100,100,color.white, 50,function()love.keypressed("right")end),
start1= newButton(880, 580,220,70, color.green, 40,function()scene.push()loadGame(0,1)end),
start2= newButton(1120, 580,220,70, color.lightPurple, 40,function()scene.push()loadGame(0,2)end),
draw= newButton(1000, 90, 190,85, color.cyan, 40,function()scene.push()scene.swapTo("draw")end),
set1= newButton(640, 160,240,75, color.lightRed, 40,function()useDefaultSet(1)end),
set2= newButton(640, 250,240,75, color.lightRed, 40,function()useDefaultSet(2)end),
set3= newButton(640, 340,240,75, color.lightRed, 40,function()useDefaultSet(3)end),
set4= newButton(640, 430,240,75, color.lightRed, 40,function()useDefaultSet(4)end),
set5= newButton(640, 520,240,75, color.lightRed, 40,function()useDefaultSet(5)end),
back= newButton(640, 630,180,60, color.white, 40,scene.back),
},
draw={
block1= newButton(920, 80, 120,120,color.red, 65,function()pen=1 end),
block2= newButton(1060, 80, 120,120,color.green, 65,function()pen=2 end),
block3= newButton(1200, 80, 120,120,color.orange, 65,function()pen=3 end),
block4= newButton(920, 220,120,120,color.blue, 65,function()pen=4 end),
block5= newButton(1060, 220,120,120,color.magenta, 65,function()pen=5 end),
block6= newButton(1200, 220,120,120,color.yellow, 65,function()pen=6 end),
block7= newButton(920, 360,120,120,color.cyan, 65,function()pen=7 end),
gb1= newButton(1060, 360,120,120,color.darkGrey, 65,function()pen=9 end),
gb2= newButton(1200, 360,120,120,color.grey, 65,function()pen=10 end),
gb3= newButton(920, 500,120,120,color.darkPurple, 65,function()pen=11 end),
gb4= newButton(1060, 500,120,120,color.darkRed, 65,function()pen=12 end),
gb5= newButton(1200, 500,120,120,color.darkGreen, 65,function()pen=13 end),
clear= newButton(780, 80, 120,120,color.white, 45,function()love.keypressed("delete")end),
any= newButton(780, 220,120,120,color.lightGrey, 45,function()pen=0 end),
space= newButton(780, 360,120,120,color.grey, 70,function()pen=-1 end),
back= newButton(1200, 640,120,120,color.white, 40,scene.back),
},
play={
pause= newButton(1235,45,80,80,color.white,30,pauseGame),
},
pause={
resume= newButton(640,290,240,100,color.white,50,resumeGame),
restart=newButton(640,445,240,100,color.white,50,function()
clearTask("play")
updateStat()
resetGameData()
scene.swapTo("play","none")
end),
setting=newButton(1150,80,200,100,color.yellow,45,function()
scene.push()
scene.swapTo("setting_sound")
end),
quit= newButton(640,600,240,100,color.white,50,scene.back),
},
setting_game={
graphic=newButton(200,80,240,80,color.lightGreen,40,function()scene.swapTo("setting_graphic")end, nil,"sound"),
sound= newButton(1080,80,240,80,color.lightGreen,40,function()scene.swapTo("setting_sound")end, nil,"dasD"),
dasD= newButton(180,230,50,50,color.white,40,function()setting.das=(setting.das-1)%31 end, nil,"dasU"),
dasU= newButton(400,230,50,50,color.white,40,function()setting.das=(setting.das+1)%31 end, nil,"arrD"),
arrD= newButton(500,230,50,50,color.white,40,function()
setting.arr=(setting.arr-1)%16
if setting.arr>setting.das then
setting.das=setting.arr
Widget.setting_game.dasU:FX()
SFX("blip_1",.4)
end
end,nil,"arrU"),
arrU= newButton(720,230,50,50,color.white,40,function()
setting.arr=(setting.arr+1)%16
if setting.arr>setting.das then
setting.das=setting.arr
Widget.setting_game.dasU:FX()
SFX("blip_1",.4)
end
end,nil,"sddasD"),
sddasD= newButton(180,340,50,50,color.white,40,function()setting.sddas=(setting.sddas-1)%11 end, nil,"sddasU"),
sddasU= newButton(400,340,50,50,color.white,40,function()setting.sddas=(setting.sddas+1)%11 end, nil,"sdarrD"),
sdarrD= newButton(500,340,50,50,color.white,40,function()setting.sdarr=(setting.sdarr-1)%4 end, nil,"sdarrU"),
sdarrU= newButton(720,340,50,50,color.white,40,function()setting.sdarr=(setting.sdarr+1)%4 end, nil,"quickR"),
quickR= newSwitch(560,430,40,function()return setting.quickR end,function()setting.quickR=not setting.quickR end, nil,"swap"),
swap= newSwitch(560,510,25,function()return setting.swap end,function()setting.swap=not setting.swap end, nil,"fine"),
fine= newSwitch(560,590,25,function()return setting.fine end,function()setting.fine=not setting.fine end, nil,"ctrl"),
ctrl= newButton(1020,230,320,80,color.white,40,function()scene.push()scene.swapTo("setting_key")end, nil,"touch"),
touch= newButton(1020,340,320,80,color.white,40,function()scene.push()scene.swapTo("setting_touch")end, nil,"back"),
back= newButton(1160,600,160,160,color.white,55,scene.back,nil,"graphic"),
},
setting_graphic={
sound= newButton(200,80,240,80,color.lightGreen,40,function()scene.swapTo("setting_sound")end, nil,"game"),
game= newButton(1080,80,240,80,color.lightGreen,40,function()scene.swapTo("setting_game")end, nil,"ghost"),
ghost= newSwitch(310,180,40,function()return setting.ghost end, function()setting.ghost= not setting.ghost end, nil,"center"),
center= newSwitch(580,180,40,function()return setting.center end, function()setting.center= not setting.center end, nil,"smo"),
smo= newSwitch(310,260,25,function()return setting.smo end, function()setting.smo= not setting.smo end, nil,"grid"),
grid= newSwitch(580,260,40,function()return setting.grid end, function()setting.grid= not setting.grid end, nil,"dropFX"),
dropFX= newSlider(310,350,373,3,40,nil,function()return setting.dropFX end, function(i)setting.dropFX=i end, nil,"shakeFX"),
shakeFX=newSlider(310,430,373,3,40,nil,function()return setting.shakeFX end, function(i)setting.shakeFX=i end, nil,"atkFX"),
atkFX= newSlider(310,510,373,3,40,nil,function()return setting.atkFX end, function(i)setting.atkFX=i end, nil,"frame"),
frame= newSlider(310,590,373,10,40,nil,function()return setting.frameMul>35 and setting.frameMul/10 or setting.frameMul/5-4 end,function(i)setting.frameMul=i<5 and 5*i+20 or 10*i end,nil,"fullscreen"),
fullscreen=newSwitch(990,180,40,function()return setting.fullscreen end,function()
setting.fullscreen=not setting.fullscreen setting.fullscreen=not setting.fullscreen
love.window.setFullscreen(setting.fullscreen) love.window.setFullscreen(setting.fullscreen)
if not setting.fullscreen then if not setting.fullscreen then
love.resize(gc.getWidth(),gc.getHeight()) love.resize(love.graphics.getWidth(),love.graphics.getHeight())
end end
end,up="vib",down="bgblock",left="bg"}, end,nil,"bg"),
bgblock={x=850,y=300, w=340,h=60,rgb=color.white, code=function() bg= newSwitch(990,250,40,function()return setting.bg end,function()setting.bg=not setting.bg end, nil,"bgblock"),
setting.bgblock=not setting.bgblock bgblock=newSwitch(990,330,40,function()return setting.bgblock end,function()
if not setting.bgblock then setting.bgblock=not setting.bgblock--if not setting.bgblock then for i=1,16 do FX_BGblock.list[i].v=3*FX_BGblock.list[i].v end end
for i=1,16 do end,nil,"skin"),
BGblockList[i].v=3*BGblockList[i].v skin= newButton(860,470,120,60,color.white,40,function()
end setting.skin=setting.skin%8+1
end
end,up="fullscreen",down="frame",left="arrU"},
frame= {x=850,y=370, w=340,h=60,rgb=color.white, code=function()
setting.frameMul=setting.frameMul+(setting.frameMul<50 and 5 or 10)
if setting.frameMul>100 then setting.frameMul=25 end
end,up="bgblock",down="skin",left="sdarrU"},
skin= {x=850,y=440, w=340,h=60,rgb=color.white, code=function()
setting.skin=setting.skin%6+1
changeBlockSkin(setting.skin) changeBlockSkin(setting.skin)
end,up="frame",down="back",left="ctrl"}, end,nil,"back"),
back= {x=640,y=620, w=300,h=70,rgb=color.white, code=back,up="lang"}, back= newButton(1160,600,160,160,color.white,55,scene.back,nil,"sound"),
},
setting_sound={
game= newButton(200,80,240,80,color.lightGreen,40,function()scene.swapTo("setting_game")end, nil,"graphic"),
graphic=newButton(1080,80,240,80,color.lightGreen,40,function()scene.swapTo("setting_graphic")end, nil,"sfx"),
sfx=newSlider(180,250,400,10,40,function()SFX("blip_1")end, function()return setting.sfx end,function(i)setting.sfx=i end,nil,"bgm"),
bgm=newSlider(750,250,400,10,40,function()BGM(bgmPlaying or"blank")end, function()return setting.bgm end,function(i)setting.bgm=i end,nil,"vib"),
vib=newSlider(180,440,400,5,40,function()VIB(1)end, function()return setting.vib end,function(i)setting.vib=i end,nil,"voc"),
voc=newSlider(750,440,400,10,40,function()VOICE("nya")end, function()return setting.voc end,function(i)setting.voc=i end,nil,"back"),
back=newButton(1160,600,160,160,color.white,55,scene.back,nil,"game"),
}, },
setting2={--Control setting setting_key={
back={x=840,y=630,w=180,h=60,rgb=color.white,code=back}, back=newButton(1140,650,200,80,color.white,50,scene.back),
}, },
setting3={--Touch setting setting_touch={
back={x=640,y=410,w=170,h=80,f=45,code=back}, hide= newSwitch(810,140,45,function()return setting.VKSwitch end,function()setting.VKSwitch=not setting.VKSwitch end),
hide={x=640,y=210,w=500,h=80,f=45,code=function() track= newSwitch(810,220,45,function()return setting.VKTrack end,function()setting.VKTrack=not setting.VKTrack end),
setting.virtualkeySwitch=not setting.virtualkeySwitch tkset= newButton(450,220,170,80,color.white,30,function()
end}, scene.push()
default={x=450,y=310,w=170,h=80,code=function() scene.swapTo("setting_trackSetting")
for K=1,#virtualkey do end,function()return not setting.VKTrack end),
local b,b0=virtualkey[K],virtualkeySet[defaultSel][K] default=newButton(450,320,170,80,color.white,40,function()
b[1],b[2],b[3],b[4]=b0[1],b0[2],b0[3],b0[4] local D=virtualkeySet[defaultSel]
end--Default virtualkey for i=1,#VK_org do
VK_org[i].ava=false
end
for n=1,#D do
local T=D[n]
if T[1]then
local B=VK_org[n]
B.ava=true
B.x,B.y,B.r=T[2],T[3],T[4]
end
end--Replace keys
defaultSel=defaultSel%5+1 defaultSel=defaultSel%5+1
end}, end),
snap={x=640,y=310,w=170,h=80,code=function() snap= newButton(640,320,170,80,color.white,40,function()
snapLevel=snapLevel%6+1 snapLevel=snapLevel%6+1
end}, end),
alpha={x=830,y=310,w=170,h=80,f=45,code=function() --VK=T,70,50,27/T,130,50,27/T,190,50,27/T,250,50,27/T,310,50,27/T,370,50,27/T,430,50,27/T,490,50,27/T,550,50,27/T,610,50,27/T,670,50,27/T,730,50,27/T,790,50,27/T,850,50,27/T,910,50,27/T,970,50,27/T,739,789,897/T,1090,50,27/T,1150,50,27/T,1210,50,27
setting.virtualkeyAlpha=(setting.virtualkeyAlpha+1)%6 alpha= newButton(830,320,170,80,color.white,45,function()
setting.VKAlpha=(setting.VKAlpha+1)%11
--Adjust virtualkey alpha --Adjust virtualkey alpha
end}, end),
icon={x=450,y=410,w=170,h=80,f=45,code=function() icon= newButton(495,420,260,80,color.white,45,function()
setting.virtualkeyIcon=not setting.virtualkeyIcon setting.VKIcon=not setting.VKIcon
--Switch virtualkey icon --Switch virtualkey icon
end}, end),
size={x=830,y=410,w=170,h=80,f=45,code=function() size= newButton(785,420,260,80,color.white,45,function()
if sel then if sel then
local b=virtualkey[sel] local B=VK_org[sel]
b[4]=b[4]+10 B.r=B.r+10
if b[4]==150 then b[4]=40 end if B.r>=150 then B.r=B.r-110 end
b[3]=b[4]^2
end end
end}, end),
toggle= newButton(495,520,260,80,color.white,45,function()
scene.push()
scene.swapTo("setting_touchSwitch")
end),
back= newButton(785,520,260,80,color.white,45,scene.back),
},
setting_touchSwitch={
b1= newSwitch(300,80, 40,VKAdisp(1),VKAcode(1)),
b2= newSwitch(300,140, 40,VKAdisp(2),VKAcode(2)),
b3= newSwitch(300,200, 40,VKAdisp(3),VKAcode(3)),
b4= newSwitch(300,260, 40,VKAdisp(4),VKAcode(4)),
b5= newSwitch(300,320, 40,VKAdisp(5),VKAcode(5)),
b6= newSwitch(300,380, 40,VKAdisp(6),VKAcode(6)),
b7= newSwitch(300,440, 40,VKAdisp(7),VKAcode(7)),
b8= newSwitch(300,500, 40,VKAdisp(8),VKAcode(8)),
b9= newSwitch(300,560, 40,VKAdisp(9),VKAcode(9)),
b10= newSwitch(300,620, 40,VKAdisp(10),VKAcode(10)),
b11= newSwitch(760,80, 40,VKAdisp(11),VKAcode(11)),
b12= newSwitch(760,140, 40,VKAdisp(12),VKAcode(12)),
b13= newSwitch(760,200, 40,VKAdisp(13),VKAcode(13)),
b14= newSwitch(760,260, 40,VKAdisp(14),VKAcode(14)),
b15= newSwitch(760,320, 40,VKAdisp(15),VKAcode(15)),
b16= newSwitch(760,380, 40,VKAdisp(16),VKAcode(16)),
b17= newSwitch(760,440, 40,VKAdisp(17),VKAcode(17)),
b18= newSwitch(760,500, 40,VKAdisp(18),VKAcode(18)),
b19= newSwitch(760,560, 40,VKAdisp(19),VKAcode(19)),
b20= newSwitch(760,620, 40,VKAdisp(20),VKAcode(20)),
norm= newButton(1080,150,240,80,color.white,50,function()for i=1,20 do VK_org[i].ava=i<11 end end),
pro= newButton(1080,300,240,80,color.white,40,function()for i=1,20 do VK_org[i].ava=true end end),
back= newButton(1080,600,240,80,color.white,50,scene.back),
},
setting_trackSetting={
VKDodge= newSwitch(400,200, 40,function()return setting.VKDodge end,function()setting.VKDodge=not setting.VKDodge end),
VKTchW= newSlider(140,310,1000,10,40,nil,function()return setting.VKTchW end,function(i)setting.VKTchW=i;setting.VKCurW=math.max(setting.VKCurW,i)end),
VKCurW= newSlider(140,370,1000,10,40,nil,function()return setting.VKCurW end,function(i)setting.VKCurW=i;setting.VKTchW=math.min(setting.VKTchW,i)end),
back= newButton(1080,600,240,80,color.white,50,scene.back),
}, },
help={ help={
back={x=640,y=590,w=180,h=60,rgb=color.white,code=back,right="qq"}, his= newButton(1050,520,230,60,color.white,40,function()scene.push()scene.swapTo("history")end,nil,"back"),
qq={x=980,y=590,w=230,h=60,hide=function()return system=="Android"end,rgb=color.white,code=function()sys.openURL("tencent://message/?uin=1046101471&Site=&Menu=yes")end,left="back"}, qq= newButton(1050,600,230,60,color.white,40,function()love.system.openURL("tencent://message/?uin=1046101471&Site=&Menu=yes")end, function()return mobile end,"his"),
back= newButton(640, 600,180,60,color.white,40,scene.back,nil,"qq"),
},
history={
prev= newButton(1155,170,180,180,color.white,70,function()love.keypressed("up")end,function()return sel==1 end),
next= newButton(1155,400,180,180,color.white,70,function()love.keypressed("down")end,function()return sel==#updateLog-22 end),
back= newButton(1155,600,180,90,color.white,40,scene.back),
}, },
stat={ stat={
back={x=640,y=590,w=180,h=60,rgb=color.white,code=back,right="path"}, path= newButton(980,620,250,60,color.white,30,function()love.system.openURL(love.filesystem.getSaveDirectory())end,function()return mobile end,"back"),
path={x=980,y=590,w=250,h=60,f=30,hide=function()return system=="Android"end,rgb=color.white,code=function()sys.openURL(fs.getSaveDirectory())end,left="back"}, back= newButton(640,620,180,60,color.white,40,scene.back,nil,"path"),
}, },
sel=nil,--selected button id(integer)
} }
for S,L in next,Widget do
for N,W in next,L do
if W.next then
W.next,L[W.next].prev=L[W.next],W
end
end
end
widget_sel=nil--selected widget object

1170
main.lua

File diff suppressed because it is too large Load Diff

693
paint.lua
View File

@@ -1,31 +1,22 @@
local gc=love.graphics local gc=love.graphics
local mt=love.math
local setFont=setFont local setFont=setFont
local Timer=love.timer.getTime local int,abs,rnd,max,min,sin=math.floor,math.abs,math.random,math.max,math.min,math.sin
local format=string.format
local attackColor={ local Timer=love.timer.getTime
{color.darkGrey,color.white}, local scr=scr
{color.grey,color.white},
{color.lightPurple,color.white},
{color.lightRed,color.white},
{color.darkGreen,color.cyan},
}
local frameColor={
[0]=color.white,
color.lightGreen,
color.lightBlue,
color.lightPurple,
color.lightOrange,
}
local modeLevelColor={ local modeLevelColor={
EASY=color.cyan, EASY=color.cyan,
NORMAL=color.green, NORMAL=color.green,
["NORMAL+"]=color.darkGreen,
HARD=color.magenta, HARD=color.magenta,
["HARD+"]=color.darkMagenta,
LUNATIC=color.red, LUNATIC=color.red,
EXTRA=color.lightMagenta, EXTRA=color.lightMagenta,
ULTIMATE=color.lightYellow, ULTIMATE=color.lightYellow,
FINAL=color.lightGrey,
["EASY+"]=color.darkCyan,
["NORMAL+"]=color.darkGreen,
["HARD+"]=color.darkMagenta,
["LUNATIC+"]=color.darkRed,
MESS=color.lightGrey, MESS=color.lightGrey,
GM=color.blue, GM=color.blue,
@@ -36,7 +27,7 @@ local modeLevelColor={
["40L"]=color.green, ["40L"]=color.green,
["100L"]=color.orange, ["100L"]=color.orange,
["400L"]=color.red, ["400L"]=color.red,
["1000L"]=color.darkRed, ["1000L"]=color.lightGrey,
} }
local dataOptL={"key","rotate","hold",nil,nil,nil,"send","recv","pend"} local dataOptL={"key","rotate","hold",nil,nil,nil,"send","recv","pend"}
local function dataOpt(i) local function dataOpt(i)
@@ -59,6 +50,10 @@ local function dataOpt(i)
return stat.pc return stat.pc
elseif i==14 then elseif i==14 then
return format("%0.2f",stat.atk/stat.row) return format("%0.2f",stat.atk/stat.row)
elseif i==15 then
return stat.extraPiece
elseif i==16 then
return max(100-int(stat.extraRate/stat.piece*10000)*.01,0).."%"
end end
end end
local statOptL={ local statOptL={
@@ -81,6 +76,8 @@ local function statOpt(i)
return stat.pc return stat.pc
elseif i==17 then elseif i==17 then
return format("%0.2f",stat.atk/stat.row) return format("%0.2f",stat.atk/stat.row)
elseif i==18 then
return stat.extraPiece.."["..(int(stat.extraRate/stat.piece*10000)*.01).."%]"
end end
end end
local miniTitle_rect={ local miniTitle_rect={
@@ -95,15 +92,17 @@ local miniTitle_rect={
} }
local function stencil_miniTitle() local function stencil_miniTitle()
for i=1,#miniTitle_rect do for i=1,#miniTitle_rect do
gc.rectangle("fill",unpack(miniTitle_rect[i])) local a,b,c,d=unpack(miniTitle_rect[i])
gc.rectangle("fill",250+a*30,150+b*30,c*30,d*30)
end end
end end
FX={ FX_BGblock={tm=150,next=7,ct=0,list={{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},}}--Falling tetrominos on background
flash=0,--Black screen(frame) FX_attack={}--Attack beam
shake=0,--Screen shake(frame) FX_badge={}--Badge thrown
beam={},--Attack beam sysFX={}
badge={},--badge thrown FX_ripple={}--Ripple&SqrShade
textFX={
appear=function(t,a) appear=function(t,a)
setFont(t.font) setFont(t.font)
gc.setColor(1,1,1,a) gc.setColor(1,1,1,a)
@@ -171,18 +170,7 @@ FX={
gc.pop() gc.pop()
end, end,
} }
local function drawAtkPointer(x,y)
function drawDial(x,y,speed)
gc.setColor(1,1,1)
mStr(int(speed),x,y-18)
gc.draw(dialCircle,x,y,nil,nil,nil,32,32)
gc.setColor(1,1,1,.6)
gc.draw(dialNeedle,x,y,2.094+(speed<=175 and .02094*speed or 4.712-52.36/(speed-125)),nil,nil,5,4)
end
function drawPixel(y,x,id)
gc.draw(blockSkin[id],30*x-30,600-30*y)
end
function drawAtkPointer(x,y)
local t=sin(Timer()*20) local t=sin(Timer()*20)
gc.setColor(.2,.7+t*.2,1,.6+t*.4) gc.setColor(.2,.7+t*.2,1,.6+t*.4)
gc.circle("fill",x,y,25,6) gc.circle("fill",x,y,25,6)
@@ -190,82 +178,56 @@ function drawAtkPointer(x,y)
gc.setColor(0,.6,1,.8-a) gc.setColor(0,.6,1,.8-a)
gc.circle("line",x,y,30*(1+a),6) gc.circle("line",x,y,30*(1+a),6)
end end
local function VirtualkeyPreview()
function VirtualkeyPreview() if setting.VKSwitch then
for i=1,#virtualkey do for i=1,#VK_org do
local c=sel==i and .8 or 1 local B=VK_org[i]
gc.setColor(c,c,c,setting.virtualkeyAlpha*.2) if B.ava then
local b=virtualkey[i] local c=sel==i and .6 or 1
gc.setLineWidth(b[4]*.07) gc.setColor(c,1,c,setting.VKAlpha*.1)
gc.circle("line",b[1],b[2],b[4]-5) gc.setLineWidth(B.r*.07)
if setting.virtualkeyIcon then gc.draw(virtualkeyIcon[i],b[1],b[2],nil,b[4]*.025,nil,18,18)end gc.circle("line",B.x,B.y,B.r)
if setting.VKIcon then gc.draw(VKIcon[i],B.x,B.y,nil,B.r*.025,nil,18,18)end
end
end
end end
end end
function drawVirtualkey() local function drawVirtualkey()
local a=setting.virtualkeyAlpha*.2 local a=setting.VKAlpha*.1
local P=players[1]
for i=1,#virtualkey do for i=1,#virtualkey do
if i~=9 or modeEnv.Fkey then if i~=9 or modeEnv.Fkey then
local p,b=virtualkeyDown[i],virtualkey[i] local B=virtualkey[i]
if p then gc.setColor(.7,.7,.7,a) if B.ava then
else gc.setColor(1,1,1,a) local _=virtualkeyDown[i]and gc.setColor(.7,.7,.7,a)or gc.setColor(1,1,1,a)--Dark magic
end gc.setLineWidth(B.r*.07)
gc.setLineWidth(b[4]*.07) local ΔY=virtualkeyPressTime[i]
gc.circle("line",b[1],b[2]+virtualkeyPressTime[i],b[4]-5) gc.circle("line",B.x,B.y+ΔY,B.r)--Outline circle
if setting.virtualkeyIcon then gc.draw(virtualkeyIcon[i],b[1],b[2]+virtualkeyPressTime[i],nil,b[4]*.025,nil,18,18)end if setting.VKIcon then
if virtualkeyPressTime[i]>0 then gc.draw(VKIcon[i],B.x,B.y+ΔY,nil,B.r*.025,nil,18,18)
gc.setColor(1,1,1,a*virtualkeyPressTime[i]*.1) end--Icon
gc.circle("line",b[1],b[2],b[4]*(1.4-virtualkeyPressTime[i]*.04)) if ΔY>0 then
gc.setColor(1,1,1,a*ΔY*.1)
gc.circle("line",B.x,B.y,B.r*(1.4-ΔY*.04))
end--Ripple
end end
end end
end end
end end
Pnt={BG={}} local Pnt={BG={}}
function Pnt.BG.none() function Pnt.BG.none()
gc.clear(.15,.15,.15) gc.clear(.15,.15,.15)
end end
function Pnt.BG.grey() function Pnt.BG.grey()
gc.clear(.3,.3,.3) gc.clear(.3,.3,.3)
end end
function Pnt.BG.lightGrey()
gc.clear(.5,.5,.5)
end
function Pnt.BG.glow() function Pnt.BG.glow()
local t=((sin(Timer()*.5)+sin(Timer()*.7)+sin(Timer()*.9+1)+sin(Timer()*1.5)+sin(Timer()*2+3))+5)*.05 local t=((sin(Timer()*.5)+sin(Timer()*.7)+sin(Timer()*.9+1)+sin(Timer()*1.5)+sin(Timer()*2+3))+5)*.05
gc.clear(t,t,t) gc.clear(t,t,t)
end end
function Pnt.BG.game1()
gc.setColor(1,1,1)
gc.draw(background1,640,360,Timer()*.15,12,nil,64,64)
end
function Pnt.BG.game2()
gc.setColor(1,.5,.5)
gc.draw(background1,640,360,Timer()*.2,12,nil,64,64)
end
function Pnt.BG.game3()
gc.setColor(.6,.6,1)
gc.draw(background1,640,360,Timer()*.25,12,nil,64,64)
end
function Pnt.BG.game4()
gc.setColor(.1,.5,.5)
local x=Timer()%4*320
gc.draw(background2,x,0,nil,10)
gc.draw(background2,x-1280,0,nil,10)
end
function Pnt.BG.game5()
local t=2.5-Timer()%20%6%2.5
if t<.5 then gc.clear(t,t,t)
else gc.clear(0,0,0)
end
end
local scs={{1,2},nil,nil,nil,nil,{1.5,1.5},{0.5,2.5}}for i=2,5 do scs[i]=scs[1]end
function Pnt.BG.game6()
local t=1.2-Timer()%10%3%1.2
if t<.5 then gc.clear(t,t,t)
else gc.clear(0,0,0)
end
gc.setColor(.3,.3,.3)
local r=7-int(Timer()*.5)%7
gc.draw(mouseBlock[r],640,360,Timer()%3.1416*6,400,400,scs[r][2]-.5,#blocks[r][0]-scs[r][1]+.5)
end
function Pnt.BG.rgb() function Pnt.BG.rgb()
gc.clear( gc.clear(
sin(Timer()*1.2)*.15+.5, sin(Timer()*1.2)*.15+.5,
@@ -279,7 +241,49 @@ function Pnt.BG.strap()
gc.draw(background2,x,0,nil,10) gc.draw(background2,x,0,nil,10)
gc.draw(background2,x-1280,0,nil,10) gc.draw(background2,x-1280,0,nil,10)
end end
local matrixT={}for i=0,15 do matrixT[i]={}for j=0,8 do matrixT[i][j]=mt.noise(i,j)+2 end end function Pnt.BG.flink()
local t=.13-Timer()%3%1.7
if t<.25 then
gc.clear(t,t,t)
else
gc.clear(0,0,0)
end
end
function Pnt.BG.game1()
gc.setColor(1,1,1)
gc.draw(background1,640,360,Timer()*.15,12,nil,64,64)
end--Rainbow
function Pnt.BG.game2()
gc.setColor(1,.5,.5)
gc.draw(background1,640,360,Timer()*.2,12,nil,64,64)
end--Red rainbow
function Pnt.BG.game3()
gc.setColor(.6,.6,1)
gc.draw(background1,640,360,Timer()*.25,12,nil,64,64)
end--Blue rainbow
function Pnt.BG.game4()
gc.setColor(.1,.5,.5)
local x=Timer()%4*320
gc.draw(background2,x,0,nil,10)
gc.draw(background2,x-1280,0,nil,10)
end--Fast strap
function Pnt.BG.game5()
local t=2.5-Timer()%20%6%2.5
if t<.5 then gc.clear(t,t,t)
else gc.clear(0,0,0)
end
end--Lightning
local scs={1,2,1,2,1,2,1,2,1,2,1.5,1.5,.5,2.5}
function Pnt.BG.game6()
local t=1.2-Timer()%10%3%1.2
if t<.5 then gc.clear(t,t,t)
else gc.clear(0,0,0)
end
gc.setColor(.3,.3,.3)
local r=7-int(Timer()*.5)%7
gc.draw(miniBlock[r],640,360,Timer()%3.1416*6,400,400,scs[2*r]-.5,#blocks[r][0]-scs[2*r-1]+.5)
end--Fast lightning&spining tetromino
local matrixT={}for i=0,15 do matrixT[i]={}for j=0,8 do matrixT[i][j]=love.math.noise(i,j)+2 end end
function Pnt.BG.matrix() function Pnt.BG.matrix()
gc.clear(.15,.15,.15) gc.clear(.15,.15,.15)
for i=0,15 do for i=0,15 do
@@ -303,14 +307,14 @@ function Pnt.load()
mStr(loadTip,640,400) mStr(loadTip,640,400)
end end
function Pnt.intro() function Pnt.intro()
gc.push() gc.stencil(stencil_miniTitle,"replace",1)
gc.translate(250,150)
gc.scale(30)
gc.stencil(stencil_miniTitle,"replace",1)
gc.setStencilTest("equal",1) gc.setStencilTest("equal",1)
gc.setColor(1,1,1,min(count,80)*.005) gc.setColor(1,1,1,min(count,80)*.005)
gc.rectangle("fill",0,0,26,14) gc.push("transform")
gc.pop() gc.translate(250,150)
gc.scale(30)
gc.rectangle("fill",0,0,26,14)
gc.pop()
gc.setColor(1,1,1,.06) gc.setColor(1,1,1,.06)
for i=41,5,-2 do for i=41,5,-2 do
gc.setLineWidth(i) gc.setLineWidth(i)
@@ -320,10 +324,15 @@ function Pnt.intro()
end end
function Pnt.main() function Pnt.main()
gc.setColor(1,1,1) gc.setColor(1,1,1)
gc.draw(titleImage,280,30,nil,1.3) gc.draw(coloredTitleImage,60,30,nil,1.3)
gc.draw(drawableText.warning,595-drawableText.warning:getWidth(),128)
setFont(35)
gc.print(gameVersion,70,125)
gc.print(system,610,100)
gc.print(modeLevel[modeID[modeSel]][levelSel],600,373)
setFont(30) setFont(30)
gc.print("Alpha V0.7.21",290,125) gc.print(text.modeName[modeSel],600,414)
gc.print(system,845,95) players[1]:demoDraw()
end end
function Pnt.mode() function Pnt.mode()
gc.setColor(1,1,1) gc.setColor(1,1,1)
@@ -348,34 +357,42 @@ function Pnt.mode()
end end
function Pnt.music() function Pnt.music()
gc.setColor(1,1,1,.3+sin(Timer()*5)*.2) gc.setColor(1,1,1,.3+sin(Timer()*5)*.2)
gc.rectangle("fill",45,98+30*sel,237,30) gc.rectangle("fill",45,98+30*sel,250,30)
gc.setColor(.8,.8,.8) gc.setColor(.8,.8,.8)
gc.draw(drawableText.musicRoom,20,20) gc.draw(drawableText.musicRoom,20,20)
gc.setColor(1,1,1) gc.setColor(1,1,1)
gc.draw(drawableText.musicRoom,22,23) gc.draw(drawableText.musicRoom,22,23)
gc.draw(drawableText.nowPlaying,520,83) gc.draw(drawableText.nowPlaying,490,390)
setFont(35) setFont(35)
for i=1,#musicID do for i=1,#musicID do
gc.print(musicID[i],50,90+30*i) gc.print(musicID[i],50,90+30*i)
end end
setFont(50) gc.draw(titleImage,640,310,nil,1.5,nil,206,35)
gc.setColor(sin(Timer()*.5)*.2+.8,sin(Timer()*.7)*.2+.8,sin(Timer())*.2+.8) if bgmPlaying then
gc.print(bgmPlaying or"",600,140) setFont(50)
gc.setColor(sin(Timer()*.5)*.2+.8,sin(Timer()*.7)*.2+.8,sin(Timer())*.2+.8)
mStr(bgmPlaying or"",630,460)
local t=-Timer()%2.3/2
if t<1 then
gc.setColor(1,1,1,t)
gc.draw(coloredTitleImage,640,310,nil,1.5+.1-.1*t,1.5+.3-.3*t,206,35)
end
end
end end
function Pnt.custom() function Pnt.custom()
gc.setColor(1,1,1,.3+sin(Timer()*8)*.2) gc.setColor(1,1,1,.3+sin(Timer()*8)*.2)
gc.rectangle("fill",25,95+40*optSel,465,40) gc.rectangle("fill",25,95+40*sel,480,40)
gc.setColor(.8,.8,.8)gc.draw(drawableText.custom,20,20) gc.setColor(.8,.8,.8)gc.draw(drawableText.custom,20,20)
gc.setColor(1,1,1)gc.draw(drawableText.custom,22,23) gc.setColor(1,1,1)gc.draw(drawableText.custom,22,23)
setFont(40) setFont(40)
for i=1,#customID do for i=1,#customID do
local k=customID[i] local k=customID[i]
local y=90+40*i local y=90+40*i
gc.printf(text.customOption[k],30,y,320,"right") gc.printf(text.customOption[k],15,y,320,"right")
if text.customVal[k]then if text.customVal[k]then
gc.print(text.customVal[k][customSel[i]],350,y) gc.print(text.customVal[k][customSel[i]],335,y)
else else
gc.print(customRange[k][customSel[i]],350,y) gc.print(customRange[k][customSel[i]],335,y)
end end
end end
end end
@@ -392,8 +409,8 @@ function Pnt.draw()
for y=1,20 do for x=1,10 do for y=1,20 do for x=1,10 do
local B=preField[y][x] local B=preField[y][x]
if B>0 then if B>0 then
drawPixel(y,x,B) gc.draw(blockSkin[B],30*x-30,600-30*y)
elseif B==0 then elseif B==-1 then
gc.line(30*x-25,605-30*y,30*x-5,625-30*y) gc.line(30*x-25,605-30*y,30*x-5,625-30*y)
gc.line(30*x-25,625-30*y,30*x-5,605-30*y) gc.line(30*x-25,625-30*y,30*x-5,605-30*y)
end end
@@ -405,13 +422,13 @@ function Pnt.draw()
gc.translate(-200,-60) gc.translate(-200,-60)
if clearSureTime>0 then if clearSureTime>0 then
gc.setColor(1,1,1,clearSureTime*.02) gc.setColor(1,1,1,clearSureTime*.02)
gc.draw(drawableText.question,1100,570) gc.draw(drawableText.question,760,11)
end end
if pen>0 then if pen>0 then
gc.setLineWidth(13) gc.setLineWidth(13)
gc.setColor(blockColor[pen]) gc.setColor(blockColor[pen])
gc.rectangle("line",945,605,70,70) gc.rectangle("line",746,460,70,70)
elseif pen==0 then elseif pen==-1 then
gc.setLineWidth(5) gc.setLineWidth(5)
gc.setColor(.9,.9,.9) gc.setColor(.9,.9,.9)
gc.line(960,620,1000,660) gc.line(960,620,1000,660)
@@ -420,277 +437,63 @@ function Pnt.draw()
end end
function Pnt.play() function Pnt.play()
for p=1,#players do for p=1,#players do
P=players[p] players[p]:draw()
if P.small then end
P.frameWait=P.frameWait-1 gc.setLineWidth(5)
if P.frameWait==0 then for i=1,#FX_attack do
P.frameWait=8 local A=FX_attack[i]
gc.setCanvas(P.canvas) gc.push("transform")
gc.clear(0,0,0,.4) local a=A.t<10 and A.a*A.t*.05 or A.t>50 and A.a*(6-A.t*.1)or A.a
gc.push("transform") gc.setColor(A.r,A.g,A.b,a*.5)
gc.origin() gc.circle("line",0,0,A.rad,A.corner)
gc.setColor(1,1,1,P.result and max(20-P.endCounter,0)*.05 or 1) local L=A.drag
local h=#P.clearing for i=1,#L,2 do
local F=P.field gc.setColor(A.r,A.g,A.b,a*i*.05)
for j=1,#F do gc.translate(L[i],L[i+1])
if j==P.clearing[h]and P.falling>-1 then gc.rotate(A.t*.1)
h=h-1 gc.circle("fill",0,0,A.rad,A.corner)
else gc.rotate(-A.t*.1)
for i=1,10 do gc.translate(-L[i],-L[i+1])
if F[j][i]>0 then
gc.draw(blockSkinmini[F[j][i]],6*i-6,120-6*j)
end
end
end
end--Field
if P.alive then
gc.setLineWidth(2)
gc.setColor(frameColor[P.strength])gc.rectangle("line",1,1,58,118)
end--Draw boarder
if modeEnv.royaleMode then
gc.setColor(1,1,1)
for i=1,P.strength do
gc.draw(badgeIcon,12*i-7,4,nil,.5)
end
end
if P.result then
gc.setColor(1,1,1,min(P.endCounter,60)*.01)
setFont(22)mStr(P.result,32,47)
setFont(20)mStr(P.rank,30,82)
end
gc.pop()
gc.setCanvas()
end end
gc.setColor(1,1,1) gc.setColor(A.r,A.g,A.b,a)
gc.draw(P.canvas,P.x,P.y,nil,P.size*10) gc.translate(A.x,A.y)
if P.killMark then gc.rotate(A.t*.1)
gc.setLineWidth(3) gc.circle("fill",0,0,A.rad,A.corner)
gc.setColor(1,0,0,min(P.endCounter,25)*.04) gc.pop()
gc.circle("line",P.centerX,P.centerY,(840-20*min(P.endCounter,30))*P.size) end--FX animation
end
else
gc.push("transform")
gc.translate(P.x,P.y)gc.scale(P.size)--Position
gc.setColor(0,0,0,.6)gc.rectangle("fill",0,0,600,690)--Background
gc.setLineWidth(7)
gc.setColor(frameColor[P.strength])gc.rectangle("line",0,0,600,690,3)--Big frame
gc.translate(150+P.fieldOffX,70+P.fieldOffY)
if P.gameEnv.grid then
gc.setLineWidth(1)
gc.setColor(1,1,1,.2)
for x=1,9 do gc.line(30*x,-10,30*x,600)end
for y=0,19 do
y=30*y+P.fieldBeneath
gc.line(0,y,300,y)
end
if P.fieldBeneath>20 then
gc.line(0,P.fieldBeneath-30,300,P.fieldBeneath-30)
end
end--Grid lines
gc.translate(0,P.fieldBeneath)
gc.setScissor(scr.x+P.absFieldX*scr.k,scr.y+P.absFieldY*scr.k,300*P.size*scr.k,610*P.size*scr.k)
local h=#P.clearing
for j=int(P.fieldBeneath/30+1),#P.field do
if j==P.clearing[h]and P.falling>-1 then
h=h-1
gc.setColor(1,1,1,P.falling/P.gameEnv.fall)
gc.rectangle("fill",0,600-30*j,320,30)
else
for i=1,10 do
if P.field[j][i]>0 then
gc.setColor(1,1,1,min(P.visTime[j][i]*.05,1))
drawPixel(j,i,P.field[j][i])
end
end
end
end--Field
for i=1,#P.shade do
local S=P.shade[i]
gc.setColor(1,1,1,S[1]*.12)
for x=S[3],S[5]do
for y=S[6],S[4]do
drawPixel(y,x,S[2])
end
end
end--shade FX
if P.waiting==-1 then
if P.gameEnv.ghost then
gc.setColor(1,1,1,.3)
for i=1,P.r do for j=1,P.c do
if P.cur.bk[i][j]then
drawPixel(i+P.y_img-1,j+P.curX-1,P.cur.color)
end
end end
end--Ghost
if P.gameEnv.block then
gc.setColor(1,1,1,P.lockDelay/P.gameEnv.lock)
for i=1,P.r do for j=1,P.c do
if P.cur.bk[i][j]then
gc.rectangle("fill",30*(j+P.curX-1)-33,597-30*(i+P.curY-1),36,36)
end
end end--BlockShade(lockdelay indicator)
gc.setColor(1,1,1)
for i=1,P.r do for j=1,P.c do
if P.cur.bk[i][j]then
drawPixel(i+P.curY-1,j+P.curX-1,P.cur.color)
end
end end--Block
end
if P.gameEnv.center then
gc.setColor(1,1,1)
local x=30*(P.curX+P.sc[2]-1)-30+15
gc.draw(spinCenter,x,600-30*(P.curY+P.sc[1]-1)+15,nil,nil,nil,4,4)
gc.setColor(1,1,1,.5)
gc.draw(spinCenter,x,600-30*(P.y_img+P.sc[1]-1)+15,nil,nil,nil,4,4)
end--Rotate center
end
--Draw game field
gc.setScissor()--In-playField mask
gc.setColor(1,1,1)
gc.draw(PTC.dust[p])
gc.translate(0,-P.fieldBeneath)
gc.setLineWidth(3)
gc.rectangle("line",-1,-11,302,612)--Draw boarder
gc.setLineWidth(2)
gc.rectangle("line",301,0,16,601.5)--Draw atkBuffer boarder
local h=0
for i=1,#P.atkBuffer do
local a=P.atkBuffer[i]
local bar=a.amount*30
if h+bar>600 then bar=600-h end
if not a.sent then
if a.time<20 then
bar=bar*(20*a.time)^.5*.05
--Appear
end
if a.countdown>0 then
gc.setColor(attackColor[a.lv][1])
gc.rectangle("fill",304,599-h,11,-bar+3)
gc.setColor(attackColor[a.lv][2])
gc.rectangle("fill",304,599-h+(-bar+3),11,-(-bar+3)*(1-a.countdown/a.cd0))
--Timing
else
local t=sin((Timer()-i)*30)*.5+.5
local c1,c2=attackColor[a.lv][1],attackColor[a.lv][2]
gc.setColor(c1[1]*t+c2[1]*(1-t),c1[2]*t+c2[2]*(1-t),c1[3]*t+c2[3]*(1-t))
gc.rectangle("fill",304,599-h,11,-bar+3)
--Warning
end
else
gc.setColor(attackColor[a.lv][1])
bar=bar*(20-a.time)*.05
gc.rectangle("fill",304,599-h,11,-bar+2)
--Disappear
end
h=h+bar
end--Buffer line
local a,b=P.b2b,P.b2b1 if a>b then a,b=b,a end
gc.setColor(.8,1,.2)
gc.rectangle("fill",-15,599.5,11,-b*.5)
gc.setColor(P.b2b<40 and color.white or P.b2b<=1e3 and color.lightRed or color.lightBlue)
gc.rectangle("fill",-15,599.5,11,-a*.5)
gc.setColor(1,1,1,.5+sin(Timer()*30)*.5)
gc.rectangle("fill",-16,b<40 and 578.5 or 98.5,13,3)
gc.setColor(1,1,1)
gc.rectangle("line",-17,-3,16,604.5)--Draw b2b bar boarder
--B2B indictator
gc.translate(-P.fieldOffX,-P.fieldOffY)
if P.gameEnv.hold then
gc.setColor(1,1,1)
mDraw(drawableText.hold,-82,-10)
for i=1,#P.hold.bk do
for j=1,#P.hold.bk[1] do
if P.hold.bk[i][j]then
drawPixel(i+17.5-#P.hold.bk*.5,j-2.7-#P.hold.bk[1]*.5,P.holded and 9 or P.hold.color)
end
end
end
end--Hold
mDraw(drawableText.next,381,-10)
local N=1
::L::
local b,c=P.next[N].bk,P.next[N].color
gc.setColor(1,1,1)
for i=1,#b do for j=1,#b[1] do
if b[i][j]then
drawPixel(i+20-2.4*N-#b*.5,j+12.7-#b[1]*.5,c)
end
end end
N=N+1
if N<=P.gameEnv.next and P.next[N]then goto L end
--Next
gc.setColor(.8,.8,.8)
gc.draw(drawableText.modeName,-135,-65)
gc.draw(drawableText.levelName,437-drawableText.levelName:getWidth(),-65)
if frame<180 then
local count=179-frame
gc.push("transform")
gc.translate(155,220)
gc.setColor(1,1,1)
setFont(100)
if count%60>45 then gc.scale(1+(count%60-45)^2*.01,1)end
mStr(int(count/60+1),0,0)
gc.pop()
end--Draw starting counter
for i=1,#P.bonus do
P.bonus[i]:draw(min((30-abs(P.bonus[i].t-30))*.05,1)*(not P.bonus[i].inf and #P.field>(9-P.bonus[i].dy*.0333)and .7 or 1))
end--Effects
gc.setColor(1,1,1)
setFont(35)
mStr(format("%.2f",P.stat.time),-82,520)--Draw time
if mesDisp[curMode.id]then mesDisp[curMode.id]()end--Draw other message
gc.setColor(1,1,1)
gc.draw(drawableText.bpm,390,490)
gc.draw(drawableText.kpm,350,583)
setFont(30)
drawDial(360,520,P.dropSpeed)
drawDial(405,575,P.keySpeed)
--Speed dials
if modeEnv.royaleMode then
if P.atkMode then
gc.setColor(1,.8,0,P.swappingAtkMode*.02)
gc.rectangle("fill",RCPB[2*P.atkMode-1],RCPB[2*P.atkMode],90,35,8,4)
end
gc.setColor(1,1,1,P.swappingAtkMode*.025)
gc.draw(royaleCtrlPad)
end
gc.pop()
end
end--Draw players
gc.setColor(1,1,1) gc.setColor(1,1,1)
gc.draw(PTC.attack[1]) if setting.VKSwitch then drawVirtualkey()end
gc.draw(PTC.attack[2])
gc.draw(PTC.attack[3])
if setting.virtualkeySwitch then drawVirtualkey()end
if modeEnv.royaleMode then if modeEnv.royaleMode then
for i=1,#FX.badge do for i=1,#FX_badge do
local b=FX.badge[i] local b=FX_badge[i]
local t=b.t<10 and 0 or b.t<50 and .5+sin(1.5*(b.t/20-1.5))*.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.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,nil,nil,14,14) if b.t<10 then
gc.draw(badgeIcon,b[1]-14,b[2]-14)
elseif b.t<50 then
local t=((b.t-10)*.025)t=(3-2*t)*t*t
gc.draw(badgeIcon,b[1]*(1-t)+b[3]*t-14,b[2]*(1-t)+b[4]*t-14)
else
gc.draw(badgeIcon,b[3]-14,b[4]-14)
end
end end
P=players[1] local P=players[1]
gc.setLineWidth(5) gc.setLineWidth(5)
gc.setColor(.8,1,0,.2) gc.setColor(.8,1,0,.2)
for i=1,#players[1].atker do for i=1,#P.atker do
local p=players[1].atker[i] local p=P.atker[i]
gc.line(p.centerX,p.centerY,P.centerX,P.centerY) gc.line(p.centerX,p.centerY,P.centerX,P.centerY)
end end
if P.atkMode~=4 then if P.atkMode~=4 then
if P.atking then drawAtkPointer(P.atking.centerX,P.atking.centerY)end if P.atking then drawAtkPointer(P.atking.centerX,P.atking.centerY)end
else else
for i=1,#players[1].atker do for i=1,#P.atker do
local p=players[1].atker[i] local p=P.atker[i]
drawAtkPointer(p.centerX,p.centerY) drawAtkPointer(p.centerX,p.centerY)
end end
end end
end end
if restartCount>0 then if restartCount>0 then
gc.setColor(0,0,0,restartCount/17) gc.setColor(0,0,0,restartCount/20)
gc.rectangle("fill",0,0,1280,720) gc.rectangle("fill",0,0,1280,720)
end end
end end
@@ -701,69 +504,93 @@ function Pnt.pause()
gc.setColor(1,1,1,pauseTimer*.02) gc.setColor(1,1,1,pauseTimer*.02)
setFont(30) setFont(30)
if pauseCount>0 then if pauseCount>0 then
gc.print(text.pauseTime..":["..pauseCount.."] "..format("%0.2f",pauseTime).."s",110,150) gc.print(text.pauseCount..":["..pauseCount.."] "..format("%0.2f",pauseTime).."s",110,150)
end end
for i=1,7 do for i=1,8 do
gc.print(text.stat[i+3],110,30*i+270) gc.print(text.stat[i+3],110,30*i+270)
gc.print(dataOpt(i),305,30*i+270) gc.print(dataOpt(i),305,30*i+270)
end end
for i=8,14 do for i=9,16 do
gc.print(text.stat[i+3],860,30*i+60) gc.print(text.stat[i+3],860,30*i+30)
gc.print(dataOpt(i),1000,30*i+60) gc.print(dataOpt(i),1050,30*i+30)
end end
setFont(40) setFont(40)
if system~="Android"then if system~="Android"then
mStr(text.space.."/"..text.enter,640,300) mStr(text.space.."/"..text.enter,640,190)
gc.print("ESC",610,598) mStr("Ctrl+R",640,351)
gc.print("ESC",610,506)
end end
mDraw(gamefinished and drawableText.finish or drawableText.pause,640,140-12*(5-pauseTimer*.1)^2) mDraw(gamefinished and drawableText.finish or drawableText.pause,640,60-10*(5-pauseTimer*.1)^1.5)
end end
function Pnt.setting() function Pnt.setting_game()
gc.setColor(1,1,1) gc.setColor(1,1,1)
setFont(35) mDraw(drawableText.setting_game,640,15)
mStr("DAS:"..setting.das,290,278) setFont(40)
mStr("ARR:"..setting.arr,506,278) mStr("DAS:"..setting.das,290,205)
setFont(21) mStr("ARR:"..setting.arr,610,205)
mStr(text.softdropdas..setting.sddas,290,357) setFont(28)
mStr(text.softdroparr..setting.sdarr,506,357) mStr(text.softdropdas..setting.sddas,290,323)
gc.draw(blockSkin[7-int(Timer()*2)%7],820,480,nil,2) mStr(text.softdroparr..setting.sdarr,610,323)
end end
function Pnt.setting2() function Pnt.setting_graphic()
gc.setColor(1,1,1)
mDraw(drawableText.setting_graphic,640,15)
gc.draw(blockSkin[7-int(Timer()*2)%7],940,440,nil,2)
end
function Pnt.setting_sound()
gc.setColor(1,1,1)
mDraw(drawableText.setting_sound,640,15)
end
function Pnt.setting_key()
local a=.3+sin(Timer()*15)*.1 local a=.3+sin(Timer()*15)*.1
if keyboardSetting then if keyboardSetting then gc.setColor(1,.3,.3,a)else gc.setColor(1,.7,.7,a)end
gc.setColor(1,.5,.5,a) gc.rectangle("fill",
else keyboardSet<11 and 240 or 840,
gc.setColor(.9,.9,.9,a) 45*keyboardSet+20-450*int(keyboardSet/11),
end 200,45
gc.rectangle("fill",240,40*keyboardSet-10,200,40) )
if joystickSetting then if joystickSetting then gc.setColor(.3,.3,.1,a)else gc.setColor(.7,.7,1,a)end
gc.setColor(1,.5,.5,a) gc.rectangle("fill",
else joystickSet<11 and 440 or 1040,
gc.setColor(.9,.9,.9,a) 45*joystickSet+20-450*int(joystickSet/11),
end 200,45
gc.rectangle("fill",440,40*joystickSet-10,200,40) )
--Selection rect
gc.setColor(1,.3,.3)
mDraw(drawableText.keyboard,340,35)
mDraw(drawableText.keyboard,940,35)
gc.setColor(.3,.3,1)
mDraw(drawableText.joystick,540,35)
mDraw(drawableText.joystick,1140,35)
gc.setColor(1,1,1) gc.setColor(1,1,1)
setFont(25) setFont(31)
for y=1,13 do for N=1,20 do
mStr(text.actName[y],150,40*y-5) if N<11 then
for x=1,2 do gc.printf(text.actName[N],47,45*N+22,180,"right")
mStr(setting.keyMap[curBoard+x*8-8][y],200*x+140,40*y-3) mStr(setting.keyMap[curBoard][N],340,45*N+22)
mStr(setting.keyMap[curBoard+8][N],540,45*N+22)
else
gc.printf(text.actName[N],647,45*N-428,180,"right")
mStr(setting.keyMap[curBoard][N],940,45*N-428)
mStr(setting.keyMap[curBoard+8][N],1040,45*N-428)
end end
gc.line(40,40*y-10,640,40*y-10)
end end
for x=1,4 do gc.setLineWidth(2)
gc.line(200*x-160,30,200*x-160,550) for x=40,1240,200 do
gc.line(x,65,x,515)
end
for y=65,515,45 do
gc.line(40,y,1240,y)
end end
gc.line(40,550,640,550)
mDraw(drawableText.keyboard,340,0)
mDraw(drawableText.joystick,540,0)
gc.draw(drawableText.setting2Help,50,620)
setFont(40) setFont(40)
gc.print("P"..int(curBoard*.5+.5).."/P4",420,560) gc.print("Player:",170,590)
gc.print(curBoard.."/8",580,560) gc.print(int(curBoard*.5+.5),300,590)
gc.print(curBoard.."/8",580,590)
gc.draw(drawableText.ctrlSetHelp,50,650)
end end
function Pnt.setting3() function Pnt.setting_touch()
VirtualkeyPreview() VirtualkeyPreview()
local d=snapLevelValue[snapLevel] local d=snapLevelValue[snapLevel]
if d>=10 then if d>=10 then
@@ -777,13 +604,21 @@ function Pnt.setting3()
end end
end end
end end
function Pnt.help() function Pnt.setting_trackSetting()
setFont(32)
gc.setColor(1,1,1) gc.setColor(1,1,1)
for i=1,11 do mDraw(drawableText.VKTchW,140+50*setting.VKTchW,260)
gc.printf(text.help[i],140,15+43*i,1000,"center") mDraw(drawableText.VKOrgW,140+50*setting.VKTchW+50*setting.VKCurW,320)
mDraw(drawableText.VKCurW,640+50*setting.VKCurW,380)
end
function Pnt.help()
setFont(30)
gc.setColor(1,1,1)
for i=1,#text.help do
gc.printf(text.help[i],140,10+40*i,1000,"center")
end end
gc.draw(titleImage,250,600,.2,1+.05*sin(Timer()*2),nil,212,35) setFont(24)
gc.print(text.used,30,330)
gc.draw(titleImage,280,620,.1,1+.05*sin(Timer()*2),nil,206,35)
gc.setLineWidth(5) gc.setLineWidth(5)
gc.rectangle("line",17,17,260,260) gc.rectangle("line",17,17,260,260)
gc.rectangle("line",1077,17,186,186) gc.rectangle("line",1077,17,186,186)
@@ -798,9 +633,21 @@ end
function Pnt.stat() function Pnt.stat()
setFont(28) setFont(28)
gc.setColor(1,1,1) gc.setColor(1,1,1)
for i=1,17 do for i=1,18 do
gc.print(text.stat[i],400,30*i-5) gc.print(text.stat[i],400,30*i-5)
gc.print(statOpt(i),720,30*i-5) gc.print(statOpt(i),720,30*i-5)
end end
gc.draw(titleImage,260,600,.2+.07*sin(Timer()*3),nil,nil,212,35) gc.draw(titleImage,260,600,.2+.07*sin(Timer()*3),nil,nil,206,35)
end end
function Pnt.history()
gc.setColor(.2,.2,.2,.7)
gc.rectangle("fill",30,45,1000,632)
gc.setColor(1,1,1)
gc.setLineWidth(4)
gc.rectangle("line",30,45,1000,632)
setFont(25)
for i=0,min(22,#updateLog-sel)do
gc.print(updateLog[sel+i],40,50+27*(i))
end
end
return Pnt

2358
player.lua Normal file

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More