This commit is contained in:
MrZ_26
2020-02-22 00:47:35 +08:00
parent 527352ce15
commit 57857ceb67
49 changed files with 909 additions and 856 deletions

Binary file not shown.

View File

@@ -1,4 +1,4 @@
gameVersion="Alpha V0.8.10" gameVersion="Alpha V0.8.11"
function love.conf(t) function love.conf(t)
t.identity="Techmino"--SaveDir name t.identity="Techmino"--SaveDir name
t.version="11.1" t.version="11.1"

View File

@@ -6,6 +6,7 @@ setting={
quickR=true, quickR=true,
swap=true, swap=true,
fine=false, fine=false,
autoPause=true,
--game --game
ghost=true,center=true, ghost=true,center=true,

View File

@@ -87,7 +87,7 @@ function loadUnlock()
end end
end end
local statOpy={ local statOpt={
"run","game","time", "run","game","time",
"extraPiece","extraRate", "extraPiece","extraRate",
"key","rotate","hold","piece","row", "key","rotate","hold","piece","row",
@@ -106,21 +106,27 @@ function loadStat()
local p=find(t[i],"=") local p=find(t[i],"=")
if p then if p then
local t,v=sub(t[i],1,p-1),sub(t[i],p+1) local t,v=sub(t[i],1,p-1),sub(t[i],p+1)
for i=1,#statOpy do for i=1,#statOpt do
if t==statOpy[i]then if t==statOpt[i]then
v=toN(v)if not v or v<0 then v=0 end v=toN(v)if not v or v<0 then v=0 end
stat[t]=v stat[t]=v
break goto L
end end
end end
if t=="lastPlay"then
v=toN(v)
mapCam.lastPlay=v and modeRanks[v]and v or 1
end
end end
::L::
end end
end end
function saveStat() function saveStat()
local t={} local t={}
for i=1,#statOpy do for i=1,#statOpt do
t[i]=statOpy[i].."="..toS(stat[statOpy[i]]) t[i]=statOpt[i].."="..toS(stat[statOpt[i]])
end end
t[#t+1]="lastPlay="..mapCam.lastPlay
t=concat(t,"\r\n") t=concat(t,"\r\n")
local F=FILE.data local F=FILE.data
@@ -198,9 +204,6 @@ function loadSetting()
K.x,K.y,K.r=toN(SK[2]),toN(SK[3]),toN(SK[4]) K.x,K.y,K.r=toN(SK[2]),toN(SK[3]),toN(SK[4])
end end
end end
elseif t=="lastPlay"then
v=toN(v)
mapCam.lastPlay=v and modeRanks[v]and v or 1
end end
end end
end end
@@ -212,6 +215,7 @@ local saveOpt={
"quickR", "quickR",
"swap", "swap",
"fine", "fine",
"autoPause",
"ghost","center", "ghost","center",
"smo","grid", "smo","grid",
@@ -256,7 +260,6 @@ function saveSetting()
local t={ local t={
"keymap="..toS(concat(map,"/")), "keymap="..toS(concat(map,"/")),
"VK="..toS(concat(vk,"/")), "VK="..toS(concat(vk,"/")),
"lastPlay="..mapCam.lastPlay,
} }
for i=1,#saveOpt do for i=1,#saveOpt do
t[#t+1]=saveOpt[i].."="..toS(setting[saveOpt[i]]) t[#t+1]=saveOpt[i].."="..toS(setting[saveOpt[i]])
@@ -268,7 +271,7 @@ function saveSetting()
F:flush() F:flush()
F:close() F:close()
if _ then if _ then
TEXT(text.settingSaved,370,330,30,"appear") newTask(Event_task.settingSaved,nil,{15})
else else
TEXT(text.settingSavingError.."123",370,350,20,"appear",.3) TEXT(text.settingSavingError.."123",370,350,20,"appear",.3)
end end

View File

@@ -240,8 +240,7 @@ return{
pause={ pause={
resume= "继续", resume= "继续",
restart="重新开始", restart="重新开始",
sfx="音效", setting="设置",
bgm="音乐",
quit= "退出", quit= "退出",
}, },
setting_game={ setting_game={
@@ -254,6 +253,7 @@ return{
reTime="开局等待时间", reTime="开局等待时间",
maxNext="最大预览数量", maxNext="最大预览数量",
quickR="快速重新开始", quickR="快速重新开始",
autoPause="自动暂停",
swap="组合键切换攻击模式", swap="组合键切换攻击模式",
fine="极简操作提示音", fine="极简操作提示音",
ctrl="键位设置", ctrl="键位设置",

View File

@@ -240,8 +240,7 @@ return{
pause={ pause={
resume= "继续", resume= "继续",
restart="重新开始", restart="重新开始",
sfx="音效", setting="设置",
bgm="音乐",
quit= "退出", quit= "退出",
}, },
@@ -254,6 +253,7 @@ return{
sdarrD="-",sdarrU="+", sdarrD="-",sdarrU="+",
reTime="开局等待时间", reTime="开局等待时间",
maxNext="最大预览数量", maxNext="最大预览数量",
autoPause="自动暂停",
quickR="快速重新开始", quickR="快速重新开始",
swap="组合键切换攻击模式", swap="组合键切换攻击模式",
fine="极简操作提示音", fine="极简操作提示音",

View File

@@ -127,7 +127,6 @@ return{
"CLASSIC SEXY RUSSIAN BLOCKS", "CLASSIC SEXY RUSSIAN BLOCKS",
"Headphones for better experience", "Headphones for better experience",
"少女祈禱中", "少女祈禱中",
"少女折壽中",
"LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI "LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI
"(first effective)Your luck number today:"..math.random(100,626), "(first effective)Your luck number today:"..math.random(100,626),
}, },
@@ -239,8 +238,7 @@ Lib used:
pause={ pause={
resume="Resume", resume="Resume",
restart="Restart", restart="Restart",
sfx="SFX", setting="Setting",
bgm="BGM",
quit="Quit", quit="Quit",
}, },
setting_game={ setting_game={
@@ -253,6 +251,7 @@ Lib used:
reTime="Delay before game", reTime="Delay before game",
maxNext="Max next count", maxNext="Max next count",
quickR="Quick restart", quickR="Quick restart",
autoPause="Auto pause",
swap="Combo key to change ATK mode", swap="Combo key to change ATK mode",
fine="Finesse error SFX", fine="Finesse error SFX",
ctrl="Key Setting", ctrl="Key Setting",

View File

@@ -56,45 +56,6 @@ blockColor={
color.darkRed, color.darkRed,
color.darkGreen, color.darkGreen,
} }
sfx={
"welcome",
"click","enter",
"finesseError","finesseError_long",
--Stereo sfxs(cannot set position)
"button","swipe",
"ready","start","win","fail","collect",
"move","rotate","rotatekick","hold",
"prerotate","prehold",
"lock","drop","fall",
"reach",
"ren_1","ren_2","ren_3","ren_4","ren_5","ren_6","ren_7","ren_8","ren_9","ren_10","ren_11","ren_mega",
"clear_1","clear_2","clear_3","clear_4",
"spin_0","spin_1","spin_2","spin_3",
"emit","blip_1","blip_2",
"perfectclear",
"error",
--Mono sfxs
}
bgm={
"blank",
"way",
"race",
"newera",
"push",
"reason",
"infinite",
"cruelty",
"final",
"secret7th",
"secret8th",
"rockblock",
"8-bit happiness",
"shining terminal",
"oxygen",
"distortion",
"end",
}
voiceBank={}--{{srcs1},{srcs2},...} voiceBank={}--{{srcs1},{srcs2},...}
voiceName={ voiceName={
"zspin","sspin","lspin","jspin","tspin","ospin","ispin", "zspin","sspin","lspin","jspin","tspin","ospin","ispin",

224
main.lua
View File

@@ -10,10 +10,8 @@ local Timer=love.timer.getTime
local int,rnd,max,min=math.floor,math.random,math.max,math.min local int,rnd,max,min=math.floor,math.random,math.max,math.min
local abs=math.abs local abs=math.abs
local rem=table.remove local rem=table.remove
package.path="?.lua"--boost
function NULL()end function NULL()end
--Libs --LIBs
------------------------------------------------------------- -------------------------------------------------------------
system=sys.getOS() system=sys.getOS()
local xOy=love.math.newTransform() local xOy=love.math.newTransform()
@@ -41,7 +39,6 @@ mapCam={
--for auto zooming when enter/leave scene --for auto zooming when enter/leave scene
} }
curBG="none" curBG="none"
bgmPlaying=nil
voiceQueue={free=0} voiceQueue={free=0}
texts={} texts={}
widget_sel=nil--selected widget object widget_sel=nil--selected widget object
@@ -58,14 +55,22 @@ ms.setVisible(false)
------------------------------------------------------------- -------------------------------------------------------------
customSel={1,22,1,1,7,3,1,1,8,4,1,1,1} customSel={1,22,1,1,7,3,1,1,8,4,1,1,1}
preField={h=20} preField={h=20}
for i=1,10 do preField[i]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}end for i=1,20 do preField[i]={0,0,0,0,0,0,0,0,0,0}end
for i=11,20 do preField[i]={0,0,0,0,0,0,0,0,0,0}end
freeRow={L=40}for i=1,40 do freeRow[i]={0,0,0,0,0,0,0,0,0,0}end freeRow={L=40}for i=1,40 do freeRow[i]={0,0,0,0,0,0,0,0,0,0}end
--Game system Vars --Game system Vars
------------------------------------------------------------- -------------------------------------------------------------
space=require("parts/space")local space=space space=require("parts/space")local space=space
setFont=require("parts/font") setFont=require("parts/setfont")
blocks=require("parts/mino") blocks=require("parts/mino")
VIB=require("parts/vib")
SFX=require("parts/sfx")
BGM=require("parts/bgm")
require("parts/voice")
Event=require("parts/event")
Event_task=require("parts/task")
AITemplate=require("parts/AITemplate")
require("parts/modes")
-- require("parts/light") -- require("parts/light")
-- require("parts/shader") -- require("parts/shader")
scene=require("scene") scene=require("scene")
@@ -74,12 +79,11 @@ require("class")
require("ai") require("ai")
require("toolfunc") require("toolfunc")
require("file") require("file")
require("sound")
require("text") require("text")
require("list") require("list")
require("player") require("player")
Widget=require("widgetList") Widget=require("widgetList")
require("dataList") -- require("dataList")
require("texture") require("texture")
local Tmr=require("timer") local Tmr=require("timer")
local Pnt=require("paint") local Pnt=require("paint")
@@ -251,7 +255,7 @@ function mouseClick.mode(x,y,k)
local __=onMode(x,y) local __=onMode(x,y)
if _~=__ then if _~=__ then
if __ then if __ then
SFX("click") SFX.play("click")
cam.moving=true cam.moving=true
_=modes[__] _=modes[__]
cam.x=_.x*cam.k+180 cam.x=_.x*cam.k+180
@@ -320,10 +324,10 @@ function keyDown.music(key)
elseif key=="up"then elseif key=="up"then
sceneTemp=(sceneTemp-2)%#musicID+1 sceneTemp=(sceneTemp-2)%#musicID+1
elseif key=="return"or key=="space"then elseif key=="return"or key=="space"then
if bgmPlaying~=musicID[sceneTemp]then if BGM.nowPlay~=musicID[sceneTemp]then
BGM(musicID[sceneTemp]) BGM.play(musicID[sceneTemp])
else else
BGM() BGM.stop()
end end
elseif key=="escape"then elseif key=="escape"then
scene.back() scene.back()
@@ -337,14 +341,14 @@ function keyDown.custom(key)
if sel==12 then if sel==12 then
curBG=customRange.bg[customSel[12]] curBG=customRange.bg[customSel[12]]
elseif sel==13 then elseif sel==13 then
BGM(customRange.bgm[customSel[13]]) BGM.play(customRange.bgm[customSel[13]])
end end
elseif key=="right"then elseif key=="right"then
customSel[sel]=customSel[sel]%#customRange[customID[sel]]+1 customSel[sel]=customSel[sel]%#customRange[customID[sel]]+1
if sel==12 then if sel==12 then
curBG=customRange.bg[customSel[sel]] curBG=customRange.bg[customSel[sel]]
elseif sel==13 then elseif sel==13 then
BGM(customRange.bgm[customSel[sel]]) BGM.play(customRange.bgm[customSel[sel]])
end end
elseif key=="down"then elseif key=="down"then
sceneTemp=sel%#customID+1 sceneTemp=sel%#customID+1
@@ -474,7 +478,7 @@ function keyDown.setting_key(key)
if key=="escape"then if key=="escape"then
if s.kS then if s.kS then
s.kS=false s.kS=false
SFX("finesseError",.5) SFX.play("finesseError",.5)
else else
scene.back() scene.back()
end end
@@ -489,30 +493,30 @@ function keyDown.setting_key(key)
end end
::L:: ::L::
setting.keyMap[s.board][s.kb]=key setting.keyMap[s.board][s.kb]=key
SFX("reach",.5) SFX.play("reach",.5)
s.kS=false s.kS=false
elseif key=="return"then elseif key=="return"then
s.kS=true s.kS=true
SFX("lock",.5) SFX.play("lock",.5)
elseif key=="up"then elseif key=="up"then
if s.kb>1 then if s.kb>1 then
s.kb=s.kb-1 s.kb=s.kb-1
SFX("move",.5) SFX.play("move",.5)
end end
elseif key=="down"then elseif key=="down"then
if s.kb<20 then if s.kb<20 then
s.kb=s.kb+1 s.kb=s.kb+1
SFX("move",.5) SFX.play("move",.5)
end end
elseif key=="left"then elseif key=="left"then
if s.board>1 then if s.board>1 then
s.board=s.board-1 s.board=s.board-1
SFX("rotate",.5) SFX.play("rotate",.5)
end end
elseif key=="right"then elseif key=="right"then
if s.board<8 then if s.board<8 then
s.board=s.board+1 s.board=s.board+1
SFX("rotate",.5) SFX.play("rotate",.5)
end end
end end
end end
@@ -521,7 +525,7 @@ function gamepadDown.setting_key(key)
if key=="back"then if key=="back"then
if s.jS then if s.jS then
s.jS=false s.jS=false
SFX("finesseError",.5) SFX.play("finesseError",.5)
else else
scene.back() scene.back()
end end
@@ -536,30 +540,30 @@ function gamepadDown.setting_key(key)
end end
::L:: ::L::
setting.keyMap[8+s.board][s.js]=key setting.keyMap[8+s.board][s.js]=key
SFX("reach",.5) SFX.play("reach",.5)
s.jS=false s.jS=false
elseif key=="start"then elseif key=="start"then
s.jS=true s.jS=true
SFX("lock",.5) SFX.play("lock",.5)
elseif key=="dpup"then elseif key=="dpup"then
if s.js>1 then if s.js>1 then
s.js=s.js-1 s.js=s.js-1
SFX("move",.5) SFX.play("move",.5)
end end
elseif key=="dpdown"then elseif key=="dpdown"then
if s.js<20 then if s.js<20 then
s.js=s.js+1 s.js=s.js+1
SFX("move",.5) SFX.play("move",.5)
end end
elseif key=="dpleft"then elseif key=="dpleft"then
if s.board>1 then if s.board>1 then
s.board=s.board-1 s.board=s.board-1
SFX("rotate",.5) SFX.play("rotate",.5)
end end
elseif key=="dpright"then elseif key=="dpright"then
if s.board<8 then if s.board<8 then
s.board=s.board+1 s.board=s.board+1
SFX("rotate",.5) SFX.play("rotate",.5)
end end
end end
end end
@@ -730,11 +734,11 @@ local function widgetPress(W,x,y)
if W.type=="button"then if W.type=="button"then
W.code() W.code()
W:FX() W:FX()
SFX("button") SFX.play("button")
VOICE("nya") VOICE("nya")
elseif W.type=="switch"then elseif W.type=="switch"then
W.code() W.code()
SFX("move",.6) SFX.play("move",.6)
elseif W.type=="slider"then elseif W.type=="slider"then
if not x then return end if not x then return end
local p,P=W.disp(),x<W.x and 0 or x>W.x+W.w and W.unit or int((x-W.x)*W.unit/W.w+.5) local p,P=W.disp(),x<W.x and 0 or x>W.x+W.w and W.unit or int((x-W.x)*W.unit/W.w+.5)
@@ -1031,9 +1035,9 @@ function love.resize(w,h)
if setting.bgspace then space.new()end if setting.bgspace then space.new()end
end end
function love.focus(f) function love.focus(f)
if system~="Android" and not f and scene.cur=="play"then pauseGame()end if scene.cur=="play"and not f and setting.autoPause then pauseGame()end
end end
function love.update(dt) local function love_update(dt)
if setting.bgspace then space.update()end if setting.bgspace then space.update()end
for i=#sysFX,1,-1 do for i=#sysFX,1,-1 do
local S=sysFX[i] local S=sysFX[i]
@@ -1122,84 +1126,9 @@ function love.update(dt)
W:update() W:update()
end--更新控件 end--更新控件
end end
function love.errorhandler(msg)
local PUMP,POLL=love.event.pump,love.event.poll
love.mouse.setVisible(true)
love.audio.stop()
local err={"Error:"..msg}
local trace=debug.traceback("",2)
local c=2
for l in string.gmatch(trace,"(.-)\n")do
if c>2 then
if not string.find(l,"boot")then
err[c]=string.gsub(l,"^\t*","")
c=c+1
end
else
err[2]="Traceback"
c=3
end
end
print(table.concat(err,"\n"),1,c-2)
-- err=err:gsub("%[string \"(.-)\"%]","%1")
local CAP
local function _(_)CAP=gc.newImage(_)end
gc.captureScreenshot(_)
local egg=rnd()>.026
local T=true
return function()
PUMP()
for e,a,_,_,_,b in POLL()do
if e=="quit"or a=="escape"then
destroyPlayers()
return 1
elseif
a=="return"or
a=="start"or
e=="mousepressed"and b==2
then
destroyPlayers()
return"restart"
elseif e=="resize"then
love.resize(a,b)
end
end
if T then
if sfx.error then
SFX("error",.8)
end
T=false
else
gc.discard()
if egg then
gc.clear(.3,.5,.9)
else
gc.clear(.62,.3,.926)
end
gc.setColor(1,1,1)
gc.push("transform")
gc.replaceTransform(xOy)
gc.draw(CAP,100,365,nil,512/CAP:getWidth(),288/CAP:getHeight())
setFont(120)
gc.print(":(",100,40)
setFont(38)
gc.printf(text.errorMsg,100,200,1280-100)
setFont(20)
gc.printf(err[1],626,360,1260-626)
gc.print("TRACEBACK",626,426)
for i=4,#err-2 do
gc.print(err[i],626,370+20*i)
end
gc.pop()
end
gc.present()
love.timer.sleep(.1)
end
end
local scs={1,2,1,2,1,2,1,2,1,2,1.5,1.5,.5,2.5} local scs={1,2,1,2,1,2,1,2,1,2,1.5,1.5,.5,2.5}
local FPS=love.timer.getFPS local FPS=love.timer.getFPS
function love.draw() local function love_draw()
gc.discard()--SPEED UPUPUP! gc.discard()--SPEED UPUPUP!
Pnt.BG[setting.bg and curBG or"grey"]() Pnt.BG[setting.bg and curBG or"grey"]()
if setting.bgspace then if setting.bgspace then
@@ -1264,6 +1193,8 @@ function love.draw()
gc.print("Tasks:"..#Task,5,_-100) gc.print("Tasks:"..#Task,5,_-100)
end--DEV info end--DEV info
end end
love.draw,love.update=NULL,NULL
function love.run() function love.run()
local T=love.timer local T=love.timer
local sleep=T.sleep local sleep=T.sleep
@@ -1285,12 +1216,12 @@ function love.run()
end end
end end
T.step() T.step()
love.update(T.getDelta()) love_update(T.getDelta())
if not mini()then if not mini()then
readyDrawFrame=readyDrawFrame+setting.frameMul readyDrawFrame=readyDrawFrame+setting.frameMul
if readyDrawFrame>=100 then if readyDrawFrame>=100 then
readyDrawFrame=readyDrawFrame-100 readyDrawFrame=readyDrawFrame-100
love.draw() love_draw()
gc.present() gc.present()
end end
end end
@@ -1307,6 +1238,77 @@ function love.run()
end end
end end
end end
function love.errorhandler(msg)
local PUMP,POLL=love.event.pump,love.event.poll
love.mouse.setVisible(true)
love.audio.stop()
local err={"Error:"..msg}
local trace=debug.traceback("",2)
local c=2
for l in string.gmatch(trace,"(.-)\n")do
if c>2 then
if not string.find(l,"boot")then
err[c]=string.gsub(l,"^\t*","")
c=c+1
end
else
err[2]="Traceback"
c=3
end
end
print(table.concat(err,"\n"),1,c-2)
local CAP
local function _(_)CAP=gc.newImage(_)end
gc.captureScreenshot(_)
gc.present()
if SFX.list.error then SFX.play("error",.8)end
local egg=rnd()>.026
local needDraw
return function()
PUMP()
for E,a,b,c,d,e in POLL()do
if E=="quit"or a=="escape"then
destroyPlayers()
return 1
elseif
a=="return"or
a=="start"or
E=="mousepressed"and e==2
then
destroyPlayers()
return"restart"
elseif E=="resize"then
love.resize(a,b)
end
needDraw=true
end
if needDraw then
gc.discard()
if egg then
gc.clear(.3,.5,.9)
else
gc.clear(.62,.3,.926)
end
gc.setColor(1,1,1)
gc.push("transform")
gc.replaceTransform(xOy)
gc.draw(CAP,100,365,nil,512/CAP:getWidth(),288/CAP:getHeight())
setFont(120)gc.print(":(",100,40)
setFont(38)gc.printf(text.errorMsg,100,200,1280-100)
setFont(20)
gc.print(system.."-"..gameVersion,100,660)
gc.printf(err[1],626,360,1260-626)
gc.print("TRACEBACK",626,426)
for i=4,#err-2 do
gc.print(err[i],626,370+20*i)
end
gc.pop()
gc.present()
needDraw=false
end
love.timer.sleep(.2)
end
end
------------------------------------------------------------- -------------------------------------------------------------
local F=love.filesystem local F=love.filesystem
if F.getInfo("data")then if F.getInfo("data")then

View File

@@ -31,7 +31,7 @@ return{
env={ env={
_20G=true, _20G=true,
drop=0,lock=15, drop=0,lock=15,
wait=10,fall=15, wait=15,fall=6,
next=3, next=3,
visible="fast", visible="fast",
freshLimit=15, freshLimit=15,

View File

@@ -22,7 +22,7 @@ return{
freshLimit=15, freshLimit=15,
pushSpeed=2, pushSpeed=2,
task=function(P) task=function(P)
if not P.control then return end if not(P.control and scene.cur=="play")then return end
if P.atkBuffer.sum==0 then if P.atkBuffer.sum==0 then
local p=#P.atkBuffer+1 local p=#P.atkBuffer+1
local B,D=P.atkBuffer,P.modeData local B,D=P.atkBuffer,P.modeData

View File

@@ -21,7 +21,7 @@ return{
fall=8, fall=8,
freshLimit=15, freshLimit=15,
task=function(P) task=function(P)
if not P.control then return end if not(P.control and scene.cur=="play")then return end
if P.atkBuffer.sum<2 then if P.atkBuffer.sum<2 then
local p=#P.atkBuffer+1 local p=#P.atkBuffer+1
local B,D=P.atkBuffer,P.modeData local B,D=P.atkBuffer,P.modeData

View File

@@ -18,9 +18,9 @@ return{
"EASY", "EASY",
}, },
info={ info={
"All-spin 入门教程", "All-spin 入门教程\n未制作完成,下块即通",
"All-spin 入门教程", "All-spin 入门教程\n未制作完成,下块即通",
"All-spin Tutorial!", "All-spin Tutorial!\nUNFINISHED drop to win",
}, },
color=color.lightGrey, color=color.lightGrey,
env={ env={
@@ -35,11 +35,6 @@ return{
newPlayer(1,340,15) newPlayer(1,340,15)
end, end,
mesDisp=function(P,dx,dy) mesDisp=function(P,dx,dy)
setFont(50)
for i=1,10 do
mStr("UNFINISHED",-126+35*i,60*i-110)
mStr("UNFINISHED",626-60*i,60*i-90)
end
end, end,
score=function(P)return{P.modeData.event,P.stat.extraRate}end, score=function(P)return{P.modeData.event,P.stat.extraRate}end,
scoreDisp=function(D)return D[1].."Stage "..format("%.2f",D[2]).."%"end, scoreDisp=function(D)return D[1].."Stage "..format("%.2f",D[2]).."%"end,

View File

@@ -66,7 +66,7 @@ return{
mDraw(drawableText.combo,-82,358) mDraw(drawableText.combo,-82,358)
mDraw(drawableText.mxcmb,-82,450) mDraw(drawableText.mxcmb,-82,450)
end, end,
score=function(P)return{min(P.combo,100),P.stat.time}end, score=function(P)return{min(P.modeData.point,100),P.stat.time}end,
scoreDisp=function(D)return D[1].." Combo "..toTime(D[2])end, scoreDisp=function(D)return D[1].." Combo "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P) getRank=function(P)

View File

@@ -8,7 +8,7 @@ local function check_LVup(P)
P.gameEnv.drop,P.gameEnv.lock=1,1 P.gameEnv.drop,P.gameEnv.lock=1,1
end end
if P.gameEnv.target>100 then if P.gameEnv.target>100 then
SFX("reach") SFX.play("reach")
end end
end end
end end
@@ -54,9 +54,9 @@ return{
mStr(P.gameEnv.target,-82,370) mStr(P.gameEnv.target,-82,370)
gc.rectangle("fill",-125,375,90,4) gc.rectangle("fill",-125,375,90,4)
end, end,
score=function(P)return{P.stat.row,P.stat.score}end, score=function(P)return{P.stat.score,P.stat.row}end,
scoreDisp=function(D)return D[1].." Lines "..D[2]end, scoreDisp=function(D)return D[1].." "..D[2].." Lines"end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]>b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P) getRank=function(P)
local L=P.stat.row local L=P.stat.row
return return

View File

@@ -22,7 +22,7 @@ return{
freshLimit=15, freshLimit=15,
pushSpeed=2, pushSpeed=2,
task=function(P) task=function(P)
if not P.control then return end if not(P.control and scene.cur=="play")then return end
P.modeData.counter=P.modeData.counter+1 P.modeData.counter=P.modeData.counter+1
local t=240-2*P.modeData.event local t=240-2*P.modeData.event
if P.modeData.counter>=t then if P.modeData.counter>=t then

View File

@@ -22,7 +22,7 @@ return{
freshLimit=15, freshLimit=15,
pushSpeed=1, pushSpeed=1,
task=function(P) task=function(P)
if not P.control then return end if not(P.control and scene.cur=="play")then return end
P.modeData.counter=P.modeData.counter+1 P.modeData.counter=P.modeData.counter+1
local t=360-P.modeData.event*2 local t=360-P.modeData.event*2
if P.modeData.counter>=t then if P.modeData.counter>=t then

View File

@@ -21,12 +21,13 @@ return{
fall=20, fall=20,
freshLimit=15, freshLimit=15,
task=function(P) task=function(P)
if not P.control then return end if not(P.control and scene.cur=="play")then return end
P.modeData.counter=P.modeData.counter+1 local D=P.modeData
if P.modeData.counter>=max(90,180-P.modeData.event)then D.counter=D.counter+1
P.modeData.counter=0 if D.counter>=max(90,180-D.event)then
P:garbageRise(10,1,rnd(10)) P:garbageRise(10,1,rnd(10))
P.modeData.event=P.modeData.event+1 D.counter=0
D.event=D.event+1
end end
end, end,
bg="game2",bgm="push", bg="game2",bgm="push",

View File

@@ -20,12 +20,13 @@ return{
drop=10,lock=30, drop=10,lock=30,
freshLimit=15, freshLimit=15,
task=function(P) task=function(P)
if not P.control then return end if not(P.control and scene.cur=="play")then return end
P.modeData.counter=P.modeData.counter+1 local D=P.modeData
if P.modeData.counter>=max(45,80-.3*P.modeData.event)then D.counter=D.counter+1
P.modeData.counter=0 if D.counter>=max(30,80-.3*D.event)then
P:garbageRise(11+P.modeData.event%3,1,rnd(10)) P:garbageRise(11+D.event%3,1,rnd(10))
P.modeData.event=P.modeData.event+1 D.counter=0
D.event=D.event+1
end end
end, end,
bg="game2",bgm="secret7th", bg="game2",bgm="secret7th",
@@ -45,8 +46,8 @@ return{
getRank=function(P) getRank=function(P)
local W=P.modeData.event local W=P.modeData.event
return return
W>=120 and 5 or W>=150 and 5 or
W>=100 and 4 or W>=110 and 4 or
W>=80 and 3 or W>=80 and 3 or
W>=50 and 2 or W>=50 and 2 or
W>=20 and 1 or W>=20 and 1 or

View File

@@ -8,7 +8,7 @@ local function check_LVup(P)
else else
P.gameEnv.drop=dropSpeed[T/10] P.gameEnv.drop=dropSpeed[T/10]
P.modeData.point=T P.modeData.point=T
SFX("reach") SFX.play("reach")
end end
end end
end end

View File

@@ -12,7 +12,7 @@ local function score(P)
end end
P.modeData.point=P.modeData.point+s P.modeData.point=P.modeData.point+s
if P.modeData.point%100==99 then if P.modeData.point%100==99 then
SFX("blip_1") SFX.play("blip_1")
elseif P.modeData.point>=100*(P.modeData.event+1)then elseif P.modeData.point>=100*(P.modeData.event+1)then
local s=P.modeData.event+1;P.modeData.event=s--level up! local s=P.modeData.event+1;P.modeData.event=s--level up!
local E=P.gameEnv local E=P.gameEnv
@@ -28,7 +28,7 @@ local function score(P)
else else
P:showText(text.stage(s),0,-120,80,"fly") P:showText(text.stage(s),0,-120,80,"fly")
end end
SFX("reach") SFX.play("reach")
end end
end end
@@ -44,9 +44,9 @@ return{
"ULTIMATE", "ULTIMATE",
}, },
info={ info={
"进阶20G", "20G:上级者的挑战",
"进阶20G", "20G:上级者的挑战",
"Advanced 20G", "20G:For Pro",
}, },
color=color.red, color=color.red,
env={ env={
@@ -75,9 +75,9 @@ return{
return a[1]>b[1]or(a[1]==b[1]and(a[2]<b[2]or a[2]==b[2]and a[3]<b[3])) return a[1]>b[1]or(a[1]==b[1]and(a[2]<b[2]or a[2]==b[2]and a[3]<b[3]))
end, end,
getRank=function(P) getRank=function(P)
local L=P.stat.clear_4
local S=P.modeData.point local S=P.modeData.point
if S==500 then if S==500 then
local L=P.stat.clear_4
return return
L>=30 and 5 or L>=30 and 5 or
L>=25 and 4 or L>=25 and 4 or

View File

@@ -11,7 +11,7 @@ local function score(P)
end end
P.modeData.point=P.modeData.point+s P.modeData.point=P.modeData.point+s
if P.modeData.point%100==99 then if P.modeData.point%100==99 then
SFX("blip_1") SFX.play("blip_1")
elseif P.modeData.point>=100*(P.modeData.event+1)then elseif P.modeData.point>=100*(P.modeData.event+1)then
local s=P.modeData.event+1;P.modeData.event=s--level up! local s=P.modeData.event+1;P.modeData.event=s--level up!
local E=P.gameEnv local E=P.gameEnv
@@ -32,7 +32,7 @@ local function score(P)
else else
P:showText(text.stage(s),0,-120,80,"fly") P:showText(text.stage(s),0,-120,80,"fly")
end end
SFX("reach") SFX.play("reach")
end end
end end
@@ -48,9 +48,9 @@ return{
"LUNATIC", "LUNATIC",
}, },
info={ info={
"初心20G", "20G:初心者适用",
"初心20G", "20G:初心者适用",
"Beginner 20G", "20G:Proper to beginner",
}, },
color=color.red, color=color.red,
env={ env={
@@ -79,9 +79,9 @@ return{
return a[1]>b[1]or(a[1]==b[1]and(a[2]<b[2]or a[2]==b[2]and a[3]<b[3])) return a[1]>b[1]or(a[1]==b[1]and(a[2]<b[2]or a[2]==b[2]and a[3]<b[3]))
end, end,
getRank=function(P) getRank=function(P)
local L=P.stat.clear_4
local S=P.modeData.point local S=P.modeData.point
if S==500 then if S==500 then
local L=P.stat.clear_4
return return
L>=30 and 5 or L>=30 and 5 or
L>=25 and 4 or L>=25 and 4 or

View File

@@ -9,7 +9,7 @@ local function score(P)
end end
local MD=P.modeData local MD=P.modeData
MD.point=MD.point+s MD.point=MD.point+s
if MD.point%100==99 then SFX("blip_1")end if MD.point%100==99 then SFX.play("blip_1")end
if int(MD.point*.01)>MD.event then if int(MD.point*.01)>MD.event then
local s=MD.event+1;MD.event=s--level up! local s=MD.event+1;MD.event=s--level up!
P:showText(text.stage(s),0,-120,80,"fly") P:showText(text.stage(s),0,-120,80,"fly")
@@ -29,7 +29,7 @@ local function score(P)
MD.point,MD.event=1000,9 MD.point,MD.event=1000,9
Event.win(P,"finish") Event.win(P,"finish")
end end
SFX("reach") SFX.play("reach")
end end
end end
@@ -45,8 +45,8 @@ return{
"FINAL", "FINAL",
}, },
info={ info={
"究极20G:无法到达的终点", "究极20G:无法触及的终点",
"究极20G:无法到达的终点", "究极20G:无法触及的终点",
"Extreme 20G:Unreachable destination", "Extreme 20G:Unreachable destination",
}, },
color=color.lightGrey, color=color.lightGrey,
@@ -81,6 +81,6 @@ return{
S>=600 and 3 or S>=600 and 3 or
S>=400 and 2 or S>=400 and 2 or
S>=200 and 1 or S>=200 and 1 or
L>=50 and 0 S>=50 and 0
end, end,
} }

View File

@@ -20,7 +20,7 @@ return{
drop=30,lock=45, drop=30,lock=45,
freshLimit=10, freshLimit=10,
task=function(P) task=function(P)
if not P.control then return end if not(P.control and scene.cur=="play")then return end
P.modeData.counter=P.modeData.counter+1 P.modeData.counter=P.modeData.counter+1
if P.modeData.counter>=max(60,150-2*P.modeData.event)and P.atkBuffer.sum<4 then if P.modeData.counter>=max(60,150-2*P.modeData.event)and P.atkBuffer.sum<4 then
P.atkBuffer[#P.atkBuffer+1]={pos=rnd(10),amount=1,countdown=30,cd0=30,time=0,sent=false,lv=1} P.atkBuffer[#P.atkBuffer+1]={pos=rnd(10),amount=1,countdown=30,cd0=30,time=0,sent=false,lv=1}

View File

@@ -20,7 +20,7 @@ return{
drop=30,lock=45, drop=30,lock=45,
freshLimit=10, freshLimit=10,
task=function(P) task=function(P)
if not P.control then return end if not(P.control and scene.cur=="play")then return end
P.modeData.counter=P.modeData.counter+1 P.modeData.counter=P.modeData.counter+1
if P.modeData.counter>=max(60,180-2*P.modeData.event)and P.atkBuffer.sum<15 then if P.modeData.counter>=max(60,180-2*P.modeData.event)and P.atkBuffer.sum<15 then
P.atkBuffer[#P.atkBuffer+1]= P.atkBuffer[#P.atkBuffer+1]=

View File

@@ -20,7 +20,7 @@ return{
drop=30,lock=45, drop=30,lock=45,
freshLimit=10, freshLimit=10,
task=function(P) task=function(P)
if not P.control then return end if not(P.control and scene.cur=="play")then return end
P.modeData.counter=P.modeData.counter+1 P.modeData.counter=P.modeData.counter+1
if P.modeData.counter>=max(60,150-P.modeData.event)and P.atkBuffer.sum<20 then if P.modeData.counter>=max(60,150-P.modeData.event)and P.atkBuffer.sum<20 then
local t=max(60,90-P.modeData.event) local t=max(60,90-P.modeData.event)

View File

@@ -20,7 +20,7 @@ return{
drop=30,lock=45, drop=30,lock=45,
freshLimit=10, freshLimit=10,
task=function(P) task=function(P)
if not P.control then return end if not(P.control and scene.cur=="play")then return end
P.modeData.counter=P.modeData.counter+1 P.modeData.counter=P.modeData.counter+1
if P.modeData.counter>=max(90,180-2*P.modeData.event)and P.atkBuffer.sum<8 then if P.modeData.counter>=max(90,180-2*P.modeData.event)and P.atkBuffer.sum<8 then
local d=P.modeData.event+1 local d=P.modeData.event+1

View File

@@ -22,7 +22,7 @@ return{
freshLimit=15, freshLimit=15,
pushSpeed=2, pushSpeed=2,
task=function(P) task=function(P)
if not P.control then return end if not(P.control and scene.cur=="play")then return end
P.modeData.counter=P.modeData.counter+1 P.modeData.counter=P.modeData.counter+1
if P.modeData.counter>=max(300,600-10*P.modeData.event)and P.atkBuffer.sum<20 then if P.modeData.counter>=max(300,600-10*P.modeData.event)and P.atkBuffer.sum<20 then
local t=max(300,480-12*P.modeData.event) local t=max(300,480-12*P.modeData.event)
@@ -33,8 +33,8 @@ return{
P.atkBuffer[p+3]={pos=rnd(10),amount=6,countdown=1.5*t,cd0=1.5*t,time=0,sent=false,lv=5} P.atkBuffer[p+3]={pos=rnd(10),amount=6,countdown=1.5*t,cd0=1.5*t,time=0,sent=false,lv=5}
P.atkBuffer.sum=P.atkBuffer.sum+20 P.atkBuffer.sum=P.atkBuffer.sum+20
P.stat.recv=P.stat.recv+20 P.stat.recv=P.stat.recv+20
P.modeData.counter=0
if P.modeData.event==31 then P:showText(text.maxspeed,0,-140,100,"appear",.6)end if P.modeData.event==31 then P:showText(text.maxspeed,0,-140,100,"appear",.6)end
P.modeData.counter=0
P.modeData.event=P.modeData.event+1 P.modeData.event=P.modeData.event+1
end end
end, end,

View File

@@ -32,7 +32,6 @@ return{
ospin=false, ospin=false,
bg="matrix",bgm="reason", bg="matrix",bgm="reason",
}, },
pauseLimit=true,
load=function() load=function()
newPlayer(1,340,15) newPlayer(1,340,15)
end, end,

View File

@@ -1,4 +1,5 @@
local gc=love.graphics local gc=love.graphics
local warnTime={60,90,105,115,116,117,118,119,120}
return{ return{
name={ name={
"限时打分", "限时打分",
@@ -17,28 +18,46 @@ return{
}, },
color=color.lightGrey, color=color.lightGrey,
env={ env={
drop=1e99,lock=1e99, drop=60,lock=60,
fall=20,
minarr=1,minsdarr=1,
task=function(P) task=function(P)
if P.stat.time>=120 then local _=P.modeData.counter+1
Event.win(P,"finish") if P.stat.time>=warnTime[_]then
if _<9 then
P.modeData.counter=_
SFX.play("ready",.7+_*.03)
else
SFX.play("start")
Event.win(P,"finish")
return true
end
end end
end, end,
bg="matrix",bgm="infinite", bg="matrix",bgm="infinite",
}, },
slowMark=true,
pauseLimit=true, pauseLimit=true,
load=function() load=function()
newPlayer(1,340,15) newPlayer(1,340,15)
end, end,
mesDisp=function(P,dx,dy) mesDisp=function(P,dx,dy)
gc.circle("line",-30,100,40) gc.setLineWidth(2)
gc.setColor(1,0,0) gc.rectangle("line",-95,112,32,402)
gc.arc("fill",-40,100,50,0,1) local T=P.stat.time/120
gc.setColor(2*T,2-2*T,.2)
gc.rectangle("fill",-94,513,30,(T-1)*400)
end, end,
score=function(P)return{P.stat.score}end, score=function(P)return{P.stat.score}end,
scoreDisp=function(D)return tostring(D[1])end, scoreDisp=function(D)return tostring(D[1])end,
comp=function(a,b)return a[1]>b[1]end, comp=function(a,b)return a[1]>b[1]end,
getRank=function(P) getRank=function(P)
local T=P.stat.score local T=P.stat.score
return 1 return
T>=62000 and 5 or
T>=50000 and 4 or
T>=26000 and 3 or
T>=10000 and 2 or
T>=6200 and 1
end, end,
} }

View File

@@ -16,7 +16,7 @@ return{
}, },
color=color.lightGrey, color=color.lightGrey,
env={ env={
drop=1e99,lock=1e99, drop=120,lock=120,
oncehold=false,target=200, oncehold=false,target=200,
dropPiece=Event.reach_winCheck, dropPiece=Event.reach_winCheck,
bg="strap",bgm="infinite", bg="strap",bgm="infinite",
@@ -35,10 +35,10 @@ return{
getRank=function(P) getRank=function(P)
local T=P.stat.score local T=P.stat.score
return return
T>=12e4 and 5 or T>=126000 and 5 or
T>=10e4 and 4 or T>=100000 and 4 or
T>=6e4 and 3 or T>=60000 and 3 or
T>=3e4 and 2 or T>=30000 and 2 or
T>=1e4 and 1 T>=10000 and 1
end, end,
} }

View File

@@ -158,7 +158,7 @@ function Pnt.BG.matrix()
end end
function Pnt.load() function Pnt.load()
local L=loading local L=sceneTemp
gc.setLineWidth(4) gc.setLineWidth(4)
gc.setColor(1,1,1,.5) gc.setColor(1,1,1,.5)
gc.rectangle("fill",300,330,L[2]/L[3]*680,60,5) gc.rectangle("fill",300,330,L[2]/L[3]*680,60,5)
@@ -166,8 +166,8 @@ function Pnt.load()
gc.rectangle("line",300,330,680,60,5) gc.rectangle("line",300,330,680,60,5)
setFont(35) setFont(35)
gc.print(text.load[L[1]],340,335) gc.print(text.load[L[1]],340,335)
if loading[1]~=0 then if sceneTemp[1]~=0 then
gc.printf(loading[2].."/"..loading[3],795,335,150,"right") gc.printf(sceneTemp[2].."/"..sceneTemp[3],795,335,150,"right")
end end
setFont(25) setFont(25)
mStr(L[4],640,400) mStr(L[4],640,400)
@@ -325,10 +325,10 @@ function Pnt.music()
gc.print(musicID[i],50,90+30*i) gc.print(musicID[i],50,90+30*i)
end end
gc.draw(titleImage,640,310,nil,1.5,nil,206,35) gc.draw(titleImage,640,310,nil,1.5,nil,206,35)
if bgmPlaying then if BGM.nowPlay then
setFont(45) setFont(45)
gc.setColor(sin(Timer()*.5)*.2+.8,sin(Timer()*.7)*.2+.8,sin(Timer())*.2+.8) gc.setColor(sin(Timer()*.5)*.2+.8,sin(Timer()*.7)*.2+.8,sin(Timer())*.2+.8)
mStr(bgmPlaying or"",630,460) mStr(BGM.nowPlay,630,460)
local t=-Timer()%2.3/2 local t=-Timer()%2.3/2
if t<1 then if t<1 then
gc.setColor(1,1,1,t) gc.setColor(1,1,1,t)
@@ -454,12 +454,15 @@ function Pnt.play()
end end
if restartCount>0 then if restartCount>0 then
gc.setColor(0,0,0,restartCount*.05) gc.setColor(0,0,0,restartCount*.05)
gc.rectangle("fill",0,0,1280,720) gc.push("transform")
gc.origin()
gc.rectangle("fill",0,0,scr.w,scr.h)
gc.pop()
end end
end end
function Pnt.pause() function Pnt.pause()
Pnt.play() Pnt.play()
gc.setColor(0,0,0,pauseTimer*.015) gc.setColor(.15,.15,.15,pauseTimer*.02)
gc.push("transform") gc.push("transform")
gc.origin() gc.origin()
gc.rectangle("fill",0,0,scr.w,scr.h) gc.rectangle("fill",0,0,scr.w,scr.h)
@@ -467,7 +470,7 @@ function Pnt.pause()
setFont(25) setFont(25)
gc.setColor(1,1,1,pauseTimer*.02) gc.setColor(1,1,1,pauseTimer*.02)
if pauseCount>0 then if pauseCount>0 then
local _=curMode.pauseLimit and(pauseCount==1 and pauseTime>2.6 or pauseTime>6.26) local _=curMode.pauseLimit and(pauseCount>4 and pauseTime>30)
if _ then gc.setColor(1,.4,.4,pauseTimer*.02)end if _ then gc.setColor(1,.4,.4,pauseTimer*.02)end
gc.print(text.pauseCount..":["..pauseCount.."] "..format("%0.2f",pauseTime).."s",110,150) gc.print(text.pauseCount..":["..pauseCount.."] "..format("%0.2f",pauseTime).."s",110,150)
if _ then gc.setColor(1,1,1,pauseTimer*.02)end if _ then gc.setColor(1,1,1,pauseTimer*.02)end
@@ -486,7 +489,7 @@ function Pnt.pause()
mStr("Ctrl+R",640,351) mStr("Ctrl+R",640,351)
gc.print("ESC",610,506) gc.print("ESC",610,506)
end end
mDraw(gameResult and drawableText[gameResult]or drawableText.pause,640,60-10*(5-pauseTimer*.1)^1.5) mDraw(gameResult and drawableText[gameResult]or drawableText.pause,640,50-10*(5-pauseTimer*.1)^1.5)
end end
function Pnt.setting_game() function Pnt.setting_game()
gc.setColor(1,1,1) gc.setColor(1,1,1)

18
parts/AITemplate.lua Normal file
View File

@@ -0,0 +1,18 @@
local int=math.floor
local AISpeed={60,50,45,35,25,15,9,6,4,2}
return function(type,speedLV,next,hold,node)
if type=="CC"then
return{
type="CC",
next=next,
hold=hold,
delta=AISpeed[speedLV],
node=node,
}
elseif type=="9S"then
return{
type="9S",
delta=int(AISpeed[speedLV]*.5),
}
end
end

88
parts/bgm.lua Normal file
View File

@@ -0,0 +1,88 @@
local rem=table.remove
local BGM={}
BGM.nowPlay=nil
BGM.playing=nil--last loaded source
BGM.playingID=nil--last loaded ID
BGM.list={
"blank",
"way",
"race",
"newera",
"push",
"reason",
"infinite",
"cruelty",
"final",
"secret7th",
"secret8th",
"rockblock",
"8-bit happiness",
"shining terminal",
"oxygen",
"distortion",
"end",
}
function BGM.loadOne(_)
_,BGM.list[_]=BGM.list[_]
BGM.list[_]=love.audio.newSource("/BGM/".._..".ogg","stream")
BGM.list[_]:setLooping(true)
BGM.list[_]:setVolume(0)
end
function BGM.loadAll()
for i=1,#BGM.list do
BGM.loadOne(i)
end
end
function BGM.play(s)
if setting.bgm==0 or not s then return end
if BGM.nowPlay~=s then
if BGM.nowPlay then newTask(Event_task.bgmFadeOut,nil,BGM.nowPlay)end
for i=#Task,1,-1 do
local T=Task[i]
if T.code==Event_task.bgmFadeIn then
T.code=Event_task.bgmFadeOut
elseif T.code==Event_task.bgmFadeOut and T.data==s then
rem(Task,i)
end
end
if s then
BGM.playingID=s
end
BGM.nowPlay=s
newTask(Event_task.bgmFadeIn,nil,s)
BGM.playing=BGM.list[s]
BGM.playing:play()
end
end
function BGM.freshVolume()
if BGM.playing then
local v=setting.bgm*.1
if v>0 then
BGM.playing:setVolume(v)
if not BGM.nowPlay then
BGM.playing:play()
BGM.nowPlay=BGM.playingID
end
else
BGM.playing:pause()
BGM.playing:setVolume(0)
BGM.nowPlay=nil
end
end
end
function BGM.stop()
if BGM.nowPlay then
for i=1,#Task do
local T=Task[i]
if T.code==Event_task.bgmFadeIn and T.data==BGM.nowPlay then
T.code=Event_task.bgmFadeOut
goto L
end
end
BGM.list[BGM.nowPlay]:stop()
::L::
BGM.nowPlay=nil
end
end
return BGM

172
parts/event.lua Normal file
View File

@@ -0,0 +1,172 @@
local int,max,min=math.floor,math.max,math.min
local ins,rem=table.insert,table.remove
local function gameOver()
saveStat()
local M=curMode
if M.pauseLimit and(pauseCount==1 and pauseTime>2.6 or pauseTime>6.26)then
TEXT(text.invalidGame,640,260,80,"flicker",.5)
return
end
local R=M.getRank
if R then
local P=players[1]
R=R(P)--new rank
if R then
local r=modeRanks[M.id]--old rank
if R>r then
modeRanks[M.id]=R
if r==0 then
for i=1,#M.unlock do
local m=M.unlock[i]
modeRanks[m]=modes[m].score and 0 or 6
end
end
saveUnlock()
end
local D=M.score(P)
local L=M.records
local p=#L--排名数-1
if p>0 then
::L::
if M.comp(D,L[p])then--是否靠前
p=p-1
if p>0 then
goto L
end
end
end
if p<10 then
if p==0 then
P:showText(text.newRecord,0,-100,100,"beat",.5)
end
D.date=os.date("%Y/%m/%d %H:%M")
ins(L,p+1,D)
if L[11]then L[11]=nil end
saveRecord(M.saveFileName,L)
end
end
end
end--Save record
local function die(P)--Same thing when win/lose,not really die!
P.alive=false
P.control=false
P.timing=false
P.waiting=1e99
P.b2b=0
clearTask(P)
for i=1,#P.atkBuffer do
P.atkBuffer[i].sent=true
P.atkBuffer[i].time=0
end
for i=1,#P.field do
for j=1,10 do
P.visTime[i][j]=min(P.visTime[i][j],20)
end
end
end
Event={}
function Event.reach_winCheck(P)
if P.stat.row>=P.gameEnv.target then
Event.win(P,"finish")
end
end
function Event.win(P,result)
die(P)
P.result="WIN"
if modeEnv.royaleMode then
P.modeData.event=1
P:changeAtk()
end
if P.human then
gameResult=result or"win"
SFX.play("win")
VOICE("win")
if modeEnv.royaleMode then
BGM.play("8-bit happiness")
end
end
newTask(Event_task.finish,P)
if curMode.id=="custom_puzzle"then
P:showText(text.win,0,0,90,"beat",.4)
else
P:showText(text.win,0,0,90,"beat",.5,.2)
end
if P.human then
gameOver()
end
end
function Event.lose(P)
if P.invincible then
while P.field[1]do
removeRow(P.field)
removeRow(P.visTime)
end
if P.AI_mode=="CC"then
P.AI_needFresh=true
end
return
end
die(P)
for i=1,#players.alive do
if players.alive[i]==P then
rem(players.alive,i)
break
end
end
P.result="K.O."
if modeEnv.royaleMode then
P:changeAtk()
P.modeData.event=#players.alive+1
P:showText(P.modeData.event,0,-120,60,"appear",1,12)
P.strength=0
if P.lastRecv then
local A,i=P,0
repeat
A,i=A.lastRecv,i+1
until not A or A.alive or A==P or i==3
if A and A.alive then
if P.id==1 or A.id==1 then
P.killMark=A.id==1
end
A.modeData.point,A.badge=A.modeData.point+1,A.badge+P.badge+1
for i=A.strength+1,4 do
if A.badge>=royaleData.powerUp[i]then
A.strength=i
end
end
P.lastRecv=A
if P.id==1 or A.id==1 then
newTask(Event_task.throwBadge,A,{P,max(3,P.badge)*4})
end
freshMostBadge()
end
else
P.badge=-1
end
freshMostDangerous()
for i=1,#players.alive do
if players.alive[i].atking==P then
players.alive[i]:freshTarget()
end
end
if #players.alive==royaleData.stage[gameStage]then
royaleLevelup()
end
end
P.gameEnv.keepVisible=P.gameEnv.visible~="show"
P:showText(text.lose,0,0,90,"appear",.5,.2)
if P.human then
gameResult="lose"
SFX.play("fail")
VOICE("lose")
if modeEnv.royaleMode then BGM.play("end")end
end
if #players.alive==1 then
Event.win(players.alive[1])
end
if #players==1 or(P.human and not players[2].human)then
gameOver()
end
newTask(#players>1 and Event_task.lose or Event_task.finish,P)
end
return Event

View File

@@ -1,265 +1,3 @@
local int,rnd,max,min=math.floor,math.random,math.max,math.min
local format=string.format
local ins,rem=table.insert,table.remove
local gc=love.graphics
local AISpeed={60,50,45,35,25,15,9,6,4,2}
function AITemplate(type,speedLV,next,hold,node)
if type=="CC"then
return{
type="CC",
next=next,
hold=hold,--hold,-------------!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
delta=AISpeed[speedLV],
node=node,
}
elseif type=="9S"then
return{
type="9S",
delta=int(AISpeed[speedLV]*.5),
}
end
end
-------------------------<Events>-------------------------
local function gameOver()
saveStat()
local M=curMode
if M.pauseLimit and(pauseCount==1 and pauseTime>2.6 or pauseTime>6.26)then
TEXT(text.invalidGame,640,260,80,"flicker",.5)
return
end
local R=M.getRank
if R then
local P=players[1]
R=R(P)--new rank
if R then
local r=modeRanks[M.id]--old rank
if R>r then
modeRanks[M.id]=R
if r==0 then
for i=1,#M.unlock do
local m=M.unlock[i]
modeRanks[m]=modes[m].score and 0 or 6
end
end
saveUnlock()
end
local D=M.score(P)
local L=M.records
local p=#L--排名数-1
if p>0 then
::L::
if M.comp(D,L[p])then--是否靠前
p=p-1
if p>0 then
goto L
end
end
end
if p<10 then
if p==0 then
P:showText(text.newRecord,0,-100,100,"beat",.5)
end
D.date=os.date("%Y/%m/%d %H:%M")
ins(L,p+1,D)
if L[11]then L[11]=nil end
saveRecord(M.saveFileName,L)
end
end
end
end--Save record
local function die(P)--Same thing when win/lose,not really die!
P.alive=false
P.control=false
P.timing=false
P.waiting=1e99
P.b2b=0
clearTask(P)
for i=1,#P.atkBuffer do
P.atkBuffer[i].sent=true
P.atkBuffer[i].time=0
end
for i=1,#P.field do
for j=1,10 do
P.visTime[i][j]=min(P.visTime[i][j],20)
end
end
end
Event={}
function Event.reach_winCheck(P)
if P.stat.row>=P.gameEnv.target then
Event.win(P,"finish")
end
end
function Event.win(P,result)
die(P)
P.result="WIN"
if modeEnv.royaleMode then
P.modeData.event=1
P:changeAtk()
end
if P.human then
gameResult=result or"win"
SFX("win")
VOICE("win")
if modeEnv.royaleMode then
BGM("8-bit happiness")
end
end
newTask(Event_task.finish,P)
if curMode.id=="custom_puzzle"then
P:showText(text.win,0,0,90,"beat",.4)
else
P:showText(text.win,0,0,90,"beat",.5,.2)
end
if P.human then
gameOver()
end
end
function Event.lose(P)
if P.invincible then
while P.field[1]do
removeRow(P.field)
removeRow(P.visTime)
end
if P.AI_mode=="CC"then
P.AI_needFresh=true
end
return
end
die(P)
for i=1,#players.alive do
if players.alive[i]==P then
rem(players.alive,i)
break
end
end
P.result="K.O."
if modeEnv.royaleMode then
P:changeAtk()
P.modeData.event=#players.alive+1
P:showText(P.modeData.event,0,-120,60,"appear",1,12)
P.strength=0
if P.lastRecv then
local A,i=P,0
repeat
A,i=A.lastRecv,i+1
until not A or A.alive or A==P or i==3
if A and A.alive then
if P.id==1 or A.id==1 then
P.killMark=A.id==1
end
A.modeData.point,A.badge=A.modeData.point+1,A.badge+P.badge+1
for i=A.strength+1,4 do
if A.badge>=royaleData.powerUp[i]then
A.strength=i
end
end
P.lastRecv=A
if P.id==1 or A.id==1 then
newTask(Event_task.throwBadge,A,{P,max(3,P.badge)*4})
end
freshMostBadge()
end
else
P.badge=-1
end
freshMostDangerous()
for i=1,#players.alive do
if players.alive[i].atking==P then
players.alive[i]:freshTarget()
end
end
if #players.alive==royaleData.stage[gameStage]then
royaleLevelup()
end
end
P.gameEnv.keepVisible=P.gameEnv.visible~="show"
P:showText(text.lose,0,0,90,"appear",.5,.2)
if P.human then
gameResult="lose"
SFX("fail")
VOICE("lose")
if modeEnv.royaleMode then BGM("end")end
end
if #players.alive==1 then
Event.win(players.alive[1])
end
if #players==1 or(P.human and not players[2].human)then
gameOver()
end
newTask(#players>1 and Event_task.lose or Event_task.finish,P)
end
-------------------------</Events>-------------------------
-------------------------<Tasks>-------------------------
Event_task={}
function Event_task.finish(P)
if scene.cur~="play"then return true end
P.endCounter=P.endCounter+1
if P.endCounter>120 then pauseGame()end
end
function Event_task.lose(P)
P.endCounter=P.endCounter+1
if P.endCounter>80 then
for i=1,#P.field do
for j=1,10 do
if P.visTime[i][j]>0 then
P.visTime[i][j]=P.visTime[i][j]-1
end
end
end
if P.endCounter==120 then
while P.field[1]do
removeRow(P.field)
removeRow(P.visTime)
end
if #players==1 and scene=="play"then
pauseGame()
end
return true
end
end
end
function Event_task.throwBadge(A,data)
data[2]=data[2]-1
if data[2]%4==0 then
local S,R=data[1],data[1].lastRecv
local x1,y1,x2,y2
if S.small then
x1,y1=S.centerX,S.centerY
else
x1,y1=S.x+308*S.size,S.y+450*S.size
end
if R.small then
x2,y2=R.centerX,R.centerY
else
x2,y2=R.x+66*R.size,R.y+344*R.size
end
FX_badge[#FX_badge+1]={x1,y1,x2,y2,t=0}
--generate badge object
if not A.ai and data[2]%8==0 then
SFX("collect")
end
end
if data[2]<=0 then return true end
end
function Event_task.bgmFadeOut(_,id)
local v=bgm[id]:getVolume()-.025*setting.bgm*.1
bgm[id]:setVolume(v>0 and v or 0)
if v<=0 then
bgm[id]:stop()
return true
end
end
function Event_task.bgmFadeIn(_,id)
local v=min(bgm[id]:getVolume()+.025*setting.bgm*.1,setting.bgm*.1)
bgm[id]:setVolume(v)
if v>=setting.bgm*.1 then return true end
end
-------------------------</Tasks>-------------------------
-------------------------<Modes>--------------------------
modes={ modes={
{"sprint_10", id=1, x=0, y=0, size=35,shape=1,icon="timer", unlock={2,3}}, {"sprint_10", id=1, x=0, y=0, size=35,shape=1,icon="timer", unlock={2,3}},
{"sprint_20", id=2, x=-300, y=0, size=45,shape=1,icon="timer", unlock={73,74,75}}, {"sprint_20", id=2, x=-300, y=0, size=45,shape=1,icon="timer", unlock={73,74,75}},
@@ -269,7 +7,7 @@ modes={
{"sprint_1000", id=6, x=-600, y=-400, size=35,shape=1,icon="timer", unlock={}}, {"sprint_1000", id=6, x=-600, y=-400, size=35,shape=1,icon="timer", unlock={}},
{"drought_normal", id=7, x=-400, y=-200, size=35,shape=1,icon="noI", unlock={8}}, {"drought_normal", id=7, x=-400, y=-200, size=35,shape=1,icon="noI", unlock={8}},
{"drought_lunatic", id=8, x=-600, y=-200, size=35,shape=1,icon="mess", unlock={}}, {"drought_lunatic", id=8, x=-600, y=-200, size=35,shape=1,icon="mess", unlock={}},
{"marathon_normal", id=9, x=0, y=-600, size=55,shape=1,icon="flag", unlock={10,11,22,31,36,37,48,68,71,72}}, {"marathon_normal", id=9, x=0, y=-600, size=55,shape=1,icon="flag", unlock={10,11,22,31,36,37,48,67,71,72}},
{"marathon_hard", id=10, x=0, y=-800, size=45,shape=1,icon="flag", unlock={27}}, {"marathon_hard", id=10, x=0, y=-800, size=45,shape=1,icon="flag", unlock={27}},
{"solo_1", id=11, x=-300, y=-1000, size=35,shape=1,icon="solo", unlock={12}}, {"solo_1", id=11, x=-300, y=-1000, size=35,shape=1,icon="solo", unlock={12}},
{"solo_2", id=12, x=-500, y=-1000, size=35,shape=1,icon="solo", unlock={13}}, {"solo_2", id=12, x=-500, y=-1000, size=35,shape=1,icon="solo", unlock={13}},
@@ -326,7 +64,7 @@ modes={
{"pcchallenge_hard", id=54, x=1000, y=-100, size=35,shape=1,icon="", unlock={55}}, {"pcchallenge_hard", id=54, x=1000, y=-100, size=35,shape=1,icon="", unlock={55}},
{"pcchallenge_lunatic", id=55, x=1200, y=-100, size=35,shape=1,icon="", unlock={}}, {"pcchallenge_lunatic", id=55, x=1200, y=-100, size=35,shape=1,icon="", unlock={}},
{"tech_normal", id=56, x=400, y=-100, size=35,shape=1,icon="", unlock={57,58}}, {"tech_normal", id=56, x=400, y=-100, size=35,shape=1,icon="", unlock={57,58}},
{"tech_normal+", id=57, x=650, y=150, size=35,shape=1,icon="", unlock={64,67}}, {"tech_normal+", id=57, x=650, y=150, size=35,shape=1,icon="", unlock={64}},
{"tech_hard", id=58, x=400, y=50, size=35,shape=1,icon="", unlock={59,60}}, {"tech_hard", id=58, x=400, y=50, size=35,shape=1,icon="", unlock={59,60}},
{"tech_hard+", id=59, x=250, y=50, size=35,shape=1,icon="", unlock={}}, {"tech_hard+", id=59, x=250, y=50, size=35,shape=1,icon="", unlock={}},
{"tech_lunatic", id=60, x=400, y=200, size=35,shape=1,icon="", unlock={61,62}}, {"tech_lunatic", id=60, x=400, y=200, size=35,shape=1,icon="", unlock={61,62}},
@@ -337,8 +75,8 @@ modes={
{"tsd_hard", id=65, x=1000, y=200, size=35,shape=1,icon="", unlock={66}}, {"tsd_hard", id=65, x=1000, y=200, size=35,shape=1,icon="", unlock={66}},
{"tsd_ultimate", id=66, x=1200, y=200, size=35,shape=1,icon="", unlock={}}, {"tsd_ultimate", id=66, x=1200, y=200, size=35,shape=1,icon="", unlock={}},
{"ultra", id=67, x=650, y=400, size=35,shape=1,icon="", unlock={}}, {"zen", id=67, x=-900, y=-600, size=35,shape=1,icon="zen", unlock={68,69,70}},
{"zen", id=68, x=-900, y=-600, size=35,shape=1,icon="zen", unlock={69,70}}, {"ultra", id=68, x=-1100, y=-400, size=35,shape=1,icon="", unlock={}},
{"infinite", id=69, x=-900, y=-400, size=35,shape=1,icon="", unlock={}}, {"infinite", id=69, x=-900, y=-400, size=35,shape=1,icon="", unlock={}},
{"infinite_dig", id=70, x=-1100, y=-600, size=35,shape=1,icon="", unlock={}}, {"infinite_dig", id=70, x=-1100, y=-600, size=35,shape=1,icon="", unlock={}},
{"custom_clear", id=71, x=200, y=-350, size=45,shape=3,icon="custom", unlock={}}, {"custom_clear", id=71, x=200, y=-350, size=45,shape=3,icon="custom", unlock={}},

67
parts/sfx.lua Normal file
View File

@@ -0,0 +1,67 @@
local rem=table.remove
local SFX={}
SFX.list={
"welcome",
"click","enter",
"finesseError","finesseError_long",
--Stereo sfxs(cannot set position)
"button","swipe",
"ready","start","win","fail","collect",
"move","rotate","rotatekick","hold",
"prerotate","prehold",
"lock","drop","fall",
"reach",
"ren_1","ren_2","ren_3","ren_4","ren_5","ren_6","ren_7","ren_8","ren_9","ren_10","ren_11","ren_mega",
"clear_1","clear_2","clear_3","clear_4",
"spin_0","spin_1","spin_2","spin_3",
"emit","blip_1","blip_2",
"perfectclear",
"error",
--Mono sfxs
}
function SFX.loadOne(_)
_,SFX.list[_]=SFX.list[_]
SFX.list[_]={love.audio.newSource("/SFX/".._..".ogg","static")}
end
function SFX.loadAll()
for i=1,#SFX.list do
SFX.loadOne(i)
end
end
function SFX.play(s,v,pos)
if setting.sfx==0 then return end
local S=SFX.list[s]--source list
local n=1
while S[n]:isPlaying()do
n=n+1
if not S[n]then
S[n]=S[n-1]:clone()
S[n]:seek(0)
break
end
end
S=S[n]--AU_SRC
if S:getChannelCount()==1 then
if pos then
pos=pos*setting.stereo*.1
S:setPosition(pos,1-pos^2,0)
else
S:setPosition(0,0,0)
end
end
S:setVolume((v or 1)*setting.sfx*.1)
S:play()
end
function SFX.reset()
for _,L in next,sfx do
for i=#v,2,-1 do
if not L[i]:isPlaying()then
rem(L,i)
end
end
end
end
return SFX

View File

@@ -7,12 +7,12 @@ local planet={}
local function newPlanet() local function newPlanet()
local a=rnd()*3.142 local a=rnd()*3.142
local r=(H+W)*(rnd()*2+1)*.06 local r=(H+W)*(2+rnd())*.05
planet.r=r planet.r=r
planet.x=W*.5+cos(a)*(R+r) planet.x=W*.5+cos(a)*(R+r)
planet.y=H*.5+sin(a)*(R+r) planet.y=H*.5+sin(a)*(R+r)
planet.vx=-cos(a+rnd()-.5)*.126 planet.vx=-cos(a+rnd()-.5)*.0626
planet.vy=-sin(a+rnd()-.5)*.126 planet.vy=-sin(a+rnd()-.5)*.0626
planet.R=.7+rnd()*.2 planet.R=.7+rnd()*.2
planet.G=.7+rnd()*.1 planet.G=.7+rnd()*.1
end end

92
parts/task.lua Normal file
View File

@@ -0,0 +1,92 @@
local min=math.min
local mini=love.window.isMinimized
local task={}
function task.pauseGame()
if not mini()then
pauseTimer=pauseTimer+1
end
return pauseTimer==50
end
function task.resumeGame()
pauseTimer=pauseTimer-1
if pauseTimer==0 then
scene.swapTo("play","none")
return true
end
end
function task.finish(P)
if scene.cur~="play"then return true end
P.endCounter=P.endCounter+1
if P.endCounter>120 then pauseGame()end
end
function task.lose(P)
P.endCounter=P.endCounter+1
if P.endCounter>80 then
for i=1,#P.field do
for j=1,10 do
if P.visTime[i][j]>0 then
P.visTime[i][j]=P.visTime[i][j]-1
end
end
end
if P.endCounter==120 then
while P.field[1]do
removeRow(P.field)
removeRow(P.visTime)
end
if #players==1 and scene=="play"then
pauseGame()
end
return true
end
end
end
function task.throwBadge(A,data)
data[2]=data[2]-1
if data[2]%4==0 then
local S,R=data[1],data[1].lastRecv
local x1,y1,x2,y2
if S.small then
x1,y1=S.centerX,S.centerY
else
x1,y1=S.x+308*S.size,S.y+450*S.size
end
if R.small then
x2,y2=R.centerX,R.centerY
else
x2,y2=R.x+66*R.size,R.y+344*R.size
end
FX_badge[#FX_badge+1]={x1,y1,x2,y2,t=0}
--generate badge object
if not A.ai and data[2]%8==0 then
SFX.play("collect")
end
end
if data[2]<=0 then return true end
end
function task.bgmFadeOut(_,id)
local src=BGM.list[id]
local v=src:getVolume()-.025*setting.bgm*.1
src:setVolume(v>0 and v or 0)
if v<=0 then
src:stop()
return true
end
end
function task.bgmFadeIn(_,id)
local src=BGM.list[id]
local v=min(src:getVolume()+.025*setting.bgm*.1,setting.bgm*.1)
src:setVolume(v)
if v>=setting.bgm*.1 then return true end
end
function task.settingSaved(_,T)
T[1]=T[1]-1
if T[1]==0 then
if scene.cur=="main"then
TEXT(text.settingSaved,370,330,30,"appear")
end
return true
end
end
return task

8
parts/vib.lua Normal file
View File

@@ -0,0 +1,8 @@
local level={0,.015,.02,.03,.04,.05,.06,.07,.08,.09}
local _=love.system.vibrate
return function(t)
local L=setting.vib
if L>0 then
_(level[L+t])
end
end

38
parts/voice.lua Normal file
View File

@@ -0,0 +1,38 @@
local rnd=math.random
function getVoice(str)
local L=voiceBank[str]
local n=1
while L[n]:isPlaying()do
n=n+1
if not L[n]then
L[n]=L[n-1]:clone()
L[n]:seek(0)
break
end
end
return L[n]
--load voice with string
end
function getFreeVoiceChannel()
local i=#voiceQueue
for i=1,i do
if #voiceQueue[i]==0 then return i end
end
voiceQueue[i+1]={s=0}
return i+1
end
function VOICE(s,chn)
if setting.voc>0 then
if chn then
local L=voiceQueue[chn]
local _=voiceList[s]
L[#L+1]=_[rnd(#_)]
L.s=1
--添加到queue[chn]
else
voiceQueue[getFreeVoiceChannel()]={s=1,voiceList[s][rnd(#voiceList[s])]}
--自动创建空轨/播放
end
end
end

View File

@@ -716,7 +716,7 @@ function player.update(P,dt)
goto stop goto stop
else else
local L=#P.clearing local L=#P.clearing
if P.human and P.gameEnv.fall>0 and #P.field+L>P.clearing[L]then SFX("fall")end if P.human and P.gameEnv.fall>0 and #P.field+L>P.clearing[L]then SFX.play("fall")end
P.clearing={} P.clearing={}
end end
end end
@@ -787,7 +787,7 @@ function player.update(P,dt)
goto stop goto stop
else else
local L=#P.clearing local L=#P.clearing
if P.human and P.gameEnv.fall>0 and #P.field+L>P.clearing[L]then SFX("fall")end if P.human and P.gameEnv.fall>0 and #P.field+L>P.clearing[L]then SFX.play("fall")end
P.clearing={} P.clearing={}
end end
end::stop:: end::stop::
@@ -968,19 +968,40 @@ local function solid(P,x,y)
if y>#P.field then return false end if y>#P.field then return false end
return P.field[y][x]>0 return P.field[y][x]>0
end end
local function getBlockDirection(P) local function getBlockPosition(P)--for stereo sfx
return(P.curX+P.sc[2]-6.5)*.15 return(P.curX+P.sc[2]-6.5)*.15
end end
local OspinList={
{111,5,2, 0,-1,false},--T
{111,5,2,-1,-1,false},--T
{111,5,0,-1, 0,false},--T
{333,5,2, -1,-1,false},--T
{333,5,2, 0,-1,false},--T
{333,5,0, 0, 0,false},--T
{313,1,2,-1, 0,false},--Z
{313,1,2, 0,-1,false},--Z
{313,1,2, 0, 0,false},--Z
{131,2,2, 0, 0,false},--S
{131,2,2,-1,-1,false},--S
{131,2,2,-1, 0,false},--S
{113,3,2,-1,-1,false},--L
{331,3,0,-1, 0,false},--L
{331,4,2, 0,-1,false},--J
{113,4,0, 0, 0,false},--J
{222,7,2,-1, 0,true},--I
{222,7,2,-2, 0,true},--I
{222,7,2, 0, 0,true},--I
}
function player.fineError(P,rate) function player.fineError(P,rate)
P.stat.extraPiece=P.stat.extraPiece+1 P.stat.extraPiece=P.stat.extraPiece+1
P.stat.extraRate=P.stat.extraRate+rate P.stat.extraRate=P.stat.extraRate+rate
if P.human then if P.human then
if P.gameEnv.fineKill then if P.gameEnv.fineKill then
SFX("finesseError_long") SFX.play("finesseError_long")
Event.lose(P) Event.lose(P)
elseif setting.fine then elseif setting.fine then
SFX("finesseError") SFX.play("finesseError")
end end
elseif P.gameEnv.fineKill then elseif P.gameEnv.fineKill then
Event.lose(P) Event.lose(P)
@@ -1011,7 +1032,7 @@ function player.garbageSend(P,R,send,time,...)
B.sum=B.sum+send B.sum=B.sum+send
R.stat.recv=R.stat.recv+send R.stat.recv=R.stat.recv+send
if R.human then if R.human then
SFX(send<4 and "blip_1"or"blip_2",min(send+1,5)*.1) SFX.play(send<4 and "blip_1"or"blip_2",min(send+1,5)*.1)
end end
end end
end end
@@ -1151,116 +1172,38 @@ function player.spin(P,d,ifpre)
end end
if P.gameEnv.ospin then if P.gameEnv.ospin then
if P.curY==P.y_img then if P.curY==P.y_img then
P.spinSeq=P.spinSeq%100*10+d local D=P.spinSeq%100*10+d
P.spinSeq=D
local id,dir--id is also success flag!
local x,y=P.curX,P.curY local x,y=P.curX,P.curY
local id for i=1,#OspinList do
if P.spinSeq==313 then--Z local L=OspinList[i]
if solid(P,x-1,y)and solid(P,x+2,y)then if D==L[1]then
if solid(P,x-1,y+2)and not solid(P,x-1,y+1)then--嵌 local id,dir=L[2],L[3]
P.curX=x-1 local bk=blocks[id][dir]
P.dir=2 local x,y=P.curX+L[4],P.curY+L[5]
id=1 if not ifoverlap(P,bk,x,y)and ifoverlap(P,bk,x,y+1)and(L[6]or ifoverlap(P,bk,x-1,y)and ifoverlap(P,bk,x+1,y))then
elseif not solid(P,x+1,y-1)and not solid(P,x+2,y-1)then--压 local C=P.cur
P.curY=y-1 C.id=id
P.dir=2 C.bk=blocks[id][dir]
id=1 P.curX,P.curY=x,y
end P.r,P.c=#C.bk,#C.bk[1]
end P.dir,P.sc=dir,scs[id][dir]
elseif P.spinSeq==131 then--S P.spinLast=2
if solid(P,x-1,y)and solid(P,x+2,y)then P.stat.rotate=P.stat.rotate+1
if solid(P,x+2,y+2)and not solid(P,x+2,y+1)then--嵌 P:freshgho()
P.dir=2 SFX.play("rotatekick",nil,getBlockPosition(P))
id=2 break
elseif not solid(P,x,y-1)and not solid(P,x-1,y-1)then--压
P.curY=y-1
P.curX=x-1
P.dir=2
id=2
end
end
elseif P.spinSeq==331 then--L
if solid(P,x-1,y+1)and solid(P,x+2,y+1)then
if solid(P,x+2,y)and not solid(P,x-1,y)then--钩
P.curX=x-1
P.dir=0
id=3
elseif not solid(P,x,y-1)and not solid(P,x+2,y)then--扣
P.curY=y-1
P.dir=2
id=3
end
end
elseif P.spinSeq==113 then--J
if solid(P,x+2,y+1)and solid(P,x-2,y+1)then
if solid(P,x-2,y)and not solid(P,x+2,y)then--钩
P.dir=0
id=4
elseif not solid(P,x+1,y-1)and not solid(P,x-1,y)then--扣
P.curX=x-1
P.curY=y-1
P.dir=2
id=4
end
end
elseif P.spinSeq==111 then--T-R
if solid(P,x+2,y+1)and solid(P,x-1,y+1)and solid(P,x+2,y)and not solid(P,x-1,y)then
if solid(P,x,y-1)then--钩
P.curX=x-1
P.dir=0
id=5
else--转
P.curY=y-1
P.dir=1
id=5
end
end
elseif P.spinSeq==333 then--T-L
if solid(P,x-1,y+1)and solid(P,x-1,y)and solid(P,x+2,y+1)and not solid(P,x+2,y)then
if solid(P,x+1,y-1)then--钩
P.dir=0
id=5
else--转
P.curY=y-1
P.dir=3
id=5
end
end
elseif P.spinSeq==222 then--I
if solid(P,x+2,y+1)and solid(P,x-1,y+1)then
if not solid(P,x-1,y)then
if not solid(P,x+2,y)then
P.curX=x-1
P.dir=2
id=7
elseif not solid(P,x-2,y)then
P.curX=x-2
P.dir=2
id=7
end
elseif not solid(P,x+2,y)and not solid(P,x+3,y)then
P.dir=2
id=7
end end
end end
end end
if id then--Transform successed return
local C=P.cur
C.id=id
C.bk=blocks[id][P.dir]
P.r,P.c=#C.bk,#C.bk[1]
P.sc=scs[id][P.dir]
P.spinLast=2
P.stat.rotate=P.stat.rotate+1
P:freshgho()
SFX("rotatekick",nil,getBlockDirection(P))
return
end
else else
P.spinSeq=0 P.spinSeq=0
end end
end end
if P.human then if P.human then
SFX(ifpre and"prerotate"or"rotate",nil,getBlockDirection(P)) SFX.play(ifpre and"prerotate"or"rotate",nil,getBlockPosition(P))
end end
return return
end end
@@ -1291,7 +1234,7 @@ function player.spin(P,d,ifpre)
if not ifpre then P:freshgho()end if not ifpre then P:freshgho()end
if P.gameEnv.easyFresh or y0>P.curY then P:freshLockDelay()end if P.gameEnv.easyFresh or y0>P.curY then P:freshLockDelay()end
if P.human then if P.human then
SFX(ifpre and"prerotate"or ifoverlap(P,P.cur.bk,P.curX,P.curY+1)and ifoverlap(P,P.cur.bk,P.curX-1,P.curY)and ifoverlap(P,P.cur.bk,P.curX+1,P.curY)and"rotatekick"or"rotate",nil,getBlockDirection(P)) SFX.play(ifpre and"prerotate"or ifoverlap(P,P.cur.bk,P.curX,P.curY+1)and ifoverlap(P,P.cur.bk,P.curX-1,P.curY)and ifoverlap(P,P.cur.bk,P.curX+1,P.curY)and"rotatekick"or"rotate",nil,getBlockPosition(P))
end end
P.stat.rotate=P.stat.rotate+1 P.stat.rotate=P.stat.rotate+1
end end
@@ -1330,7 +1273,7 @@ function player.hold(P,ifpre)
if ifoverlap(P,P.cur.bk,P.curX,P.curY)then P:lock()Event.lose(P)end if ifoverlap(P,P.cur.bk,P.curX,P.curY)then P:lock()Event.lose(P)end
if P.human then if P.human then
SFX(ifpre and"prehold"or"hold") SFX.play(ifpre and"prehold"or"hold")
end end
P.stat.hold=P.stat.hold+1 P.stat.hold=P.stat.hold+1
end end
@@ -1533,7 +1476,7 @@ function player.drop(P)--Place piece
P.lastClear=P.cur.id*10+cc P.lastClear=P.cur.id*10+cc
clearKey=spin_n clearKey=spin_n
if P.human then if P.human then
SFX(spin_n[cc]) SFX.play(spin_n[cc])
VOICE(spinName[P.cur.name],CHN) VOICE(spinName[P.cur.name],CHN)
end end
elseif #P.field>0 then elseif #P.field>0 then
@@ -1560,23 +1503,23 @@ function player.drop(P)--Place piece
send=send^.5+min(6+P.stat.pc,10) send=send^.5+min(6+P.stat.pc,10)
exblock=exblock+2 exblock=exblock+2
sendTime=sendTime+60 sendTime=sendTime+60
if P.stat.row>4 then if P.stat.row+cc>4 then
P.b2b=1200 P.b2b=1200
cscore=cscore+500*min(6+P.stat.pc,10) cscore=cscore+300*min(6+P.stat.pc,10)
else else
cscore=cscore+500 cscore=cscore+626
end end
P.stat.pc=P.stat.pc+1 P.stat.pc=P.stat.pc+1
P.lastClear=P.cur.id*10+5 P.lastClear=P.cur.id*10+5
if P.human then if P.human then
SFX("perfectclear") SFX.play("perfectclear")
VOICE("pc",CHN) VOICE("pc",CHN)
end end
end end
if P.human then if P.human then
SFX(clear_n[cc]) SFX.play(clear_n[cc])
SFX(ren_n[min(P.combo,11)]) SFX.play(ren_n[min(P.combo,11)])
if P.combo>14 then SFX("ren_mega",(P.combo-10)*.1)end if P.combo>14 then SFX.play("ren_mega",(P.combo-10)*.1)end
VIB(cc+1) VIB(cc+1)
end end
if P.b2b>1200 then P.b2b=1200 end if P.b2b>1200 then P.b2b=1200 end
@@ -1645,7 +1588,7 @@ function player.drop(P)--Place piece
P:garbageSend(T,send,sendTime,1,P.cur.color,P.lastClear,dospin,mini,P.combo) P:garbageSend(T,send,sendTime,1,P.cur.color,P.lastClear,dospin,mini,P.combo)
end end
P.stat.send=P.stat.send+send P.stat.send=P.stat.send+send
if P.human and send>3 then SFX("emit",min(send,8)*.1)end if P.human and send>3 then SFX.play("emit",min(send,8)*.1)end
end end
end end
else else
@@ -1656,7 +1599,7 @@ function player.drop(P)--Place piece
P.b2b=P.b2b+20 P.b2b=P.b2b+20
P.stat.spin_0=P.stat.spin_0+1 P.stat.spin_0=P.stat.spin_0+1
if P.human then if P.human then
SFX("spin_0") SFX.play("spin_0")
VOICE(spinName[P.cur.name],CHN) VOICE(spinName[P.cur.name],CHN)
end end
dropScore=25--spin bonus dropScore=25--spin bonus
@@ -1688,7 +1631,7 @@ function player.drop(P)--Place piece
if _ then if _ then
_(P) _(P)
end end
if P.human then SFX("lock",nil,getBlockDirection(P))end if P.human then SFX.play("lock",nil,getBlockPosition(P))end
end end
function player.pressKey(P,i) function player.pressKey(P,i)
P.keyPressing[i]=true P.keyPressing[i]=true
@@ -1696,8 +1639,8 @@ function player.pressKey(P,i)
virtualkeyDown[i]=true virtualkeyDown[i]=true
virtualkeyPressTime[i]=10 virtualkeyPressTime[i]=10
end end
P.act[actName[i]](P)
if P.alive then if P.alive then
P.act[actName[i]](P)
P.keyTime[11]=ins(P.keyTime,1,frame) P.keyTime[11]=ins(P.keyTime,1,frame)
P.stat.key=P.stat.key+1 P.stat.key=P.stat.key+1
end end
@@ -1728,7 +1671,7 @@ function player.act.moveLeft(P,auto)
local y0=P.curY local y0=P.curY
P:freshgho() P:freshgho()
if P.gameEnv.easyFresh or y0~=P.curY then P:freshLockDelay()end if P.gameEnv.easyFresh or y0~=P.curY then P:freshLockDelay()end
if P.human and P.curY==P.y_img then SFX("move")end if P.human and P.curY==P.y_img then SFX.play("move")end
P.spinLast=false P.spinLast=false
if not auto then if not auto then
P.moving=-1 P.moving=-1
@@ -1754,7 +1697,7 @@ function player.act.moveRight(P,auto)
local y0=P.curY local y0=P.curY
P:freshgho() P:freshgho()
if P.gameEnv.easyFresh or y0~=P.curY then P:freshLockDelay()end if P.gameEnv.easyFresh or y0~=P.curY then P:freshLockDelay()end
if P.human and P.curY==P.y_img then SFX("move")end if P.human and P.curY==P.y_img then SFX.play("move")end
P.spinLast=false P.spinLast=false
if not auto then if not auto then
P.moving=1 P.moving=1
@@ -1806,7 +1749,7 @@ function player.act.hardDrop(P)
P.fieldOff.vy=setting.shakeFX*.6 P.fieldOff.vy=setting.shakeFX*.6
end end
if P.human then if P.human then
SFX("drop",nil,getBlockDirection(P)) SFX.play("drop",nil,getBlockPosition(P))
VIB(1) VIB(1)
end end
end end

View File

@@ -4,17 +4,17 @@ local scene={
swapping=false,--ifSwapping swapping=false,--ifSwapping
swap={ swap={
tar=nil, --Swapping target tar=nil, --Swapping target
style=nil, --Swapping target style=nil, --Swapping style
mid=nil, --Loading point mid=nil, --Loading point
time=nil, --Full swap time time=nil, --Full swap time
draw=nil, --Swap draw draw=nil, --Swap draw func
}, },
seq={"quit","slowFade"},--Back sequence seq={"quit","slowFade"},--Back sequence
}--scene datas,returned }--scene datas,returned
local sceneInit={ local sceneInit={
quit=love.event.quit, quit=love.event.quit,
load=function() load=function()
loading={ sceneTemp={
1,--Loading mode 1,--Loading mode
1,--Loading counter 1,--Loading counter
#voiceName,--Loading bar lenth(current) #voiceName,--Loading bar lenth(current)
@@ -23,11 +23,11 @@ local sceneInit={
end, end,
intro=function() intro=function()
sceneTemp=0--animation timer sceneTemp=0--animation timer
BGM("blank") BGM.play("blank")
end, end,
main=function() main=function()
curBG="none" curBG="none"
BGM("blank") BGM.play("blank")
destroyPlayers() destroyPlayers()
modeEnv={} modeEnv={}
if not players[1]then if not players[1]then
@@ -35,9 +35,9 @@ local sceneInit={
end--create demo player end--create demo player
end, end,
music=function() music=function()
if bgmPlaying then if BGM.nowPlay then
for i=1,#musicID do for i=1,#musicID do
if musicID[i]==bgmPlaying then if musicID[i]==BGM.nowPlay then
sceneTemp=i--music select sceneTemp=i--music select
return return
end end
@@ -48,7 +48,7 @@ local sceneInit={
end, end,
mode=function() mode=function()
curBG="none" curBG="none"
BGM("blank") BGM.play("blank")
destroyPlayers() destroyPlayers()
local cam=mapCam local cam=mapCam
cam.zoomK=scene.swap.tar=="mode"and 5 or 1 cam.zoomK=scene.swap.tar=="mode"and 5 or 1
@@ -62,7 +62,7 @@ local sceneInit={
sceneTemp=1--option select sceneTemp=1--option select
destroyPlayers() destroyPlayers()
curBG=customRange.bg[customSel[12]] curBG=customRange.bg[customSel[12]]
BGM(customRange.bgm[customSel[13]]) BGM.play(customRange.bgm[customSel[13]])
end, end,
draw=function() draw=function()
curBG="none" curBG="none"
@@ -79,8 +79,6 @@ local sceneInit={
if needResetGameData then if needResetGameData then
resetGameData() resetGameData()
needResetGameData=nil needResetGameData=nil
else
BGM(modeEnv.bgm)
end end
curBG=modeEnv.bg curBG=modeEnv.bg
end, end,

102
sound.lua
View File

@@ -1,102 +0,0 @@
local rnd=math.random
local rem=table.remove
local vibrateLevel={0,.015,.02,.03,.04,.05,.06,.07,.08,.09}
function VIB(t)
if setting.vib>0 then
love.system.vibrate(vibrateLevel[setting.vib+t])
end
end
function SFX(s,v,pos)
if setting.sfx>0 then
local S=sfx[s]--AU_Queue
local n=1
while S[n]:isPlaying()do
n=n+1
if not S[n]then
S[n]=S[n-1]:clone()
S[n]:seek(0)
break
end
end
S=S[n]--AU_SRC
if S:getChannelCount()==1 then
if pos then
pos=pos*setting.stereo*.1
S:setPosition(pos,1-pos^2,0)
else
S:setPosition(0,0,0)
end
end
S:setVolume((v or 1)*setting.sfx*.1)
S:play()
end
end
function getVoice(str)
local L=voiceBank[str]
local n=1
while L[n]:isPlaying()do
n=n+1
if not L[n]then
L[n]=L[n-1]:clone()
L[n]:seek(0)
break
end
end
return L[n]
--load voice with string
end
function getFreeVoiceChannel()
local i=#voiceQueue
for i=1,i do
if #voiceQueue[i]==0 then return i end
end
voiceQueue[i+1]={s=0}
return i+1
end
function VOICE(s,chn)
if setting.voc>0 then
if chn then
local L=voiceQueue[chn]
local _=voiceList[s]
L[#L+1]=_[rnd(#_)]
L.s=1
--添加到queue[chn]
else
voiceQueue[getFreeVoiceChannel()]={s=1,voiceList[s][rnd(#voiceList[s])]}
--自动创建空轨/播放
end
end
end
function BGM(s)
if setting.bgm>0 then
if bgmPlaying~=s then
if bgmPlaying then newTask(Event_task.bgmFadeOut,nil,bgmPlaying)end
for i=#Task,1,-1 do
local T=Task[i]
if T.code==Event_task.bgmFadeIn then
T.code=Event_task.bgmFadeOut
elseif T.code==Event_task.bgmFadeOut and T.data==s then
rem(Task,i)
end
end
if s then
newTask(Event_task.bgmFadeIn,nil,s)
bgm[s]:play()
end
bgmPlaying=s
else
if bgmPlaying then
local v=setting.bgm*.1
bgm[bgmPlaying]:setVolume(v)
if v>0 then
bgm[bgmPlaying]:play()
else
bgm[bgmPlaying]:pause()
end
end
end
elseif bgmPlaying then
bgm[bgmPlaying]:pause()
bgmPlaying=nil
end
end

View File

@@ -1,4 +1,3 @@
local wd=love.window
local gc=love.graphics local gc=love.graphics
local kb=love.keyboard local kb=love.keyboard
local Timer=love.timer.getTime local Timer=love.timer.getTime
@@ -8,7 +7,7 @@ local ins,rem=table.insert,table.remove
local Tmr={} local Tmr={}
function Tmr.load() function Tmr.load()
local t=Timer() local t=Timer()
local L=loading local L=sceneTemp
::R:: ::R::
--L={stage,curPos,curLen} --L={stage,curPos,curLen}
if L[1]==1 then if L[1]==1 then
@@ -19,24 +18,18 @@ function Tmr.load()
end end
L[2]=L[2]+1 L[2]=L[2]+1
if L[2]>L[3]then if L[2]>L[3]then
L[1],L[2],L[3]=2,1,#bgm L[1],L[2],L[3]=2,1,#BGM.list
end end
elseif L[1]==2 then elseif L[1]==2 then
local N=bgm[L[2]] BGM.loadOne(L[2])
bgm[N]=love.audio.newSource("/BGM/"..N..".ogg","stream")
bgm[N]:setLooping(true)
bgm[N]:setVolume(0)
L[2]=L[2]+1 L[2]=L[2]+1
if L[2]>L[3]then if L[2]>L[3]then
for i=1,L[3]do bgm[i]=nil end L[1],L[2],L[3]=3,1,#SFX.list
L[1],L[2],L[3]=3,1,#sfx
end end
elseif L[1]==3 then elseif L[1]==3 then
local S=sfx[L[2]] SFX.loadOne(L[2])
sfx[S]={love.audio.newSource("/SFX/"..S..".ogg","static")}
L[2]=L[2]+1 L[2]=L[2]+1
if L[2]>L[3]then if L[2]>L[3]then
for i=1,L[3]do sfx[i]=nil end
L[1],L[2],L[3]=4,1,#modes L[1],L[2],L[3]=4,1,#modes
end end
elseif L[1]==4 then elseif L[1]==4 then
@@ -79,7 +72,7 @@ function Tmr.load()
} }
-------------------------- --------------------------
L[1],L[2],L[3]=0,1,1 L[1],L[2],L[3]=0,1,1
SFX("welcome",.2) SFX.play("welcome",.2)
else else
L[2]=L[2]+1 L[2]=L[2]+1
L[3]=L[2] L[3]=L[2]
@@ -117,20 +110,22 @@ local function dumpTable(L)
end end
function Tmr.mode(dt) function Tmr.mode(dt)
local cam=mapCam local cam=mapCam
local F
local x,y,k=cam.x,cam.y,cam.k local x,y,k=cam.x,cam.y,cam.k
if kb.isDown("up", "w")then y=y-10*k;F=true end local F
if kb.isDown("down","s")then y=y+10*k;F=true end if not scene.swapping then
if kb.isDown("left","a")then x=x-10*k;F=true end if kb.isDown("up", "w")then y=y-10*k;F=true end
if kb.isDown("right","d")then x=x+10*k;F=true end if kb.isDown("down","s")then y=y+10*k;F=true end
local js1=joysticks[1] if kb.isDown("left","a")then x=x-10*k;F=true end
if js1 then if kb.isDown("right","d")then x=x+10*k;F=true end
local k=js1:getAxis(1) local js1=joysticks[1]
if k~="c"then if js1 then
if k=="u"or k=="ul"or k=="ur"then y=y-10*k;F=true end local k=js1:getAxis(1)
if k=="d"or k=="dl"or k=="dl"then y=y+10*k;F=true end if k~="c"then
if k=="l"or k=="ul"or k=="dl"then x=x-10*k;F=true end if k=="u"or k=="ul"or k=="ur"then y=y-10*k;F=true end
if k=="r"or k=="ur"or k=="dr"then x=x+10*k;F=true end if k=="d"or k=="dl"or k=="dl"then y=y+10*k;F=true end
if k=="l"or k=="ul"or k=="dl"then x=x-10*k;F=true end
if k=="r"or k=="ur"or k=="dr"then x=x+10*k;F=true end
end
end end
end end
if F or cam.keyCtrl and(x-cam.x1)^2+(y-cam.y1)^2>2.6 then if F or cam.keyCtrl and(x-cam.x1)^2+(y-cam.y1)^2>2.6 then
@@ -153,7 +148,7 @@ function Tmr.mode(dt)
end end
if __ and cam.sel~=__ then if __ and cam.sel~=__ then
cam.sel=__ cam.sel=__
SFX("click") SFX.play("click")
end end
end end
end end
@@ -237,7 +232,7 @@ function Tmr.play(dt)
if frame==179 then if frame==179 then
gameStart() gameStart()
elseif frame==60 or frame==120 then elseif frame==60 or frame==120 then
SFX("ready") SFX.play("ready")
end end
for p=1,#players do for p=1,#players do
local P=players[p] local P=players[p]
@@ -274,9 +269,6 @@ function Tmr.pause(dt)
if not gameResult then if not gameResult then
pauseTime=pauseTime+dt pauseTime=pauseTime+dt
end end
if pauseTimer<50 and not wd.isMinimized()then
pauseTimer=pauseTimer+1
end
end end
function Tmr.setting_sound() function Tmr.setting_sound()
local t=sceneTemp.jump local t=sceneTemp.jump

View File

@@ -178,7 +178,7 @@ function pasteBoard()
end--str end end--str end
__=_%16--low4b __=_%16--low4b
_=(_-__)/16--high4b _=(_-__)/16--high4b
if _>12 or __>12 then goto ERROR end--illegal blockid if _>13 or __>13 then goto ERROR end--illegal blockid
if _<9 then _=_-1 end if __<9 then __=__-1 end if _<9 then _=_-1 end if __<9 then __=__-1 end
preField[fY][fX]=_;preField[fY][fX+1]=__ preField[fY][fX]=_;preField[fY][fX+1]=__
if fX<9 then if fX<9 then
@@ -254,7 +254,7 @@ function royaleLevelup()
elseif gameStage==3 then elseif gameStage==3 then
spd=15 spd=15
garbageSpeed=.6 garbageSpeed=.6
if players[1].alive then BGM("cruelty")end if players[1].alive then BGM.play("cruelty")end
elseif gameStage==4 then elseif gameStage==4 then
spd=10 spd=10
local _=players.alive local _=players.alive
@@ -266,7 +266,7 @@ function royaleLevelup()
garbageSpeed=1 garbageSpeed=1
elseif gameStage==6 then elseif gameStage==6 then
spd=3 spd=3
if players[1].alive then BGM("final")end if players[1].alive then BGM.play("final")end
end end
for i=1,#players.alive do for i=1,#players.alive do
players.alive[i].gameEnv.drop=spd players.alive[i].gameEnv.drop=spd
@@ -284,23 +284,27 @@ function royaleLevelup()
end end
end end
function pauseGame() function pauseGame()
restartCount=0--Avoid strange darkness if pauseTimer==0 then
pauseTimer=0--Pause timer for animation restartCount=0--Avoid strange darkness
if not gameResult then newTask(Event_task.pauseGame)
pauseCount=pauseCount+1 if not gameResult then
end pauseCount=pauseCount+1
for i=1,#players do end
local l=players[i].keyPressing for i=1,#players do
for j=1,#l do local l=players[i].keyPressing
if l[j]then for j=1,#l do
players[i]:releaseKey(j) if l[j]then
players[i]:releaseKey(j)
end
end end
end end
scene.swapTo("pause","none")
end end
scene.swapTo("pause","none")
end end
function resumeGame() function resumeGame()
scene.swapTo("play","fade") if pauseTimer==50 then
newTask(Event_task.resumeGame)
end
end end
function loadGame(M) function loadGame(M)
--rec={} --rec={}
@@ -312,10 +316,11 @@ function loadGame(M)
drawableText.levelName:set(M.level[lang]) drawableText.levelName:set(M.level[lang])
needResetGameData=true needResetGameData=true
scene.swapTo("play","fade_togame") scene.swapTo("play","fade_togame")
SFX("enter") SFX.play("enter")
end end
function resetPartGameData() function resetPartGameData()
gameResult=false gameResult=false
pauseTimer=0
frame=150-setting.reTime*15 frame=150-setting.reTime*15
destroyPlayers() destroyPlayers()
curMode.load() curMode.load()
@@ -335,11 +340,13 @@ function resetPartGameData()
players[i]:changeAtk(randomTarget(players[i])) players[i]:changeAtk(randomTarget(players[i]))
end end
end end
BGM.play(modeEnv.bgm)
restoreVirtualKey() restoreVirtualKey()
collectgarbage() collectgarbage()
end end
function resetGameData() function resetGameData()
gameResult=false gameResult=false
pauseTimer=0--Pause timer for animation
frame=150-setting.reTime*15 frame=150-setting.reTime*15
garbageSpeed=1 garbageSpeed=1
pauseTime=0--Time paused pauseTime=0--Time paused
@@ -353,7 +360,7 @@ function resetGameData()
end end
end end
curBG=modeEnv.bg curBG=modeEnv.bg
BGM(modeEnv.bgm) BGM.play(modeEnv.bgm)
texts={} texts={}
FX_badge={} FX_badge={}
@@ -377,11 +384,11 @@ function resetGameData()
virtualkeyPressTime[i]=0 virtualkeyPressTime[i]=0
end end
freeRow.L=#freeRow freeRow.L=#freeRow
SFX("ready") SFX.play("ready")
collectgarbage() collectgarbage()
end end
function gameStart() function gameStart()
SFX("start") SFX.play("start")
for P=1,#players do for P=1,#players do
P=players[P] P=players[P]
P:resetblock() P:resetblock()

View File

@@ -11,13 +11,13 @@ local S=[=[
?[D*a] ?[D*a]
Future outlook: Future outlook:
New mode system with: New mode system with:
rythem mode Bigbang
combo mode Rythem
puzzle mode(ttt) Combo
square mode Square
infinite 1v1 Infinite battle
Other: Other:
puzzle import/output(ttt) game recording
classic face direction classic face direction
(powerinfo switch) (powerinfo switch)
virtualWidgets like joysticks virtualWidgets like joysticks
@@ -25,22 +25,32 @@ Future outlook:
custom block color/direction custom block color/direction
custom block sequence custom block sequence
CC smarter(think of garbage buffer) CC smarter(think of garbage buffer)
game recording
new AI:task-Z new AI:task-Z
more FXs & 3d features & animations more FXs & 3d features & animations
Encrypt source code(compile to byte code) Encrypt source code(compile to byte code)
0.8.11:
better rule of checking invalid game
can setting when pause
opaque background when pause
many code optimized(moduled)
fixed:receive attack when paused in survivor mode
fixed:error when pasteboard has block_13
fixed:must hold R to restart when finished the game
fixed:sth about screen size
fixed:some O-spin error
fixed:line counting when pc(full b2b)
0.8.10: 0.8.10:
new BGM:Distortion new BGM:Distortion(master-final)
all background darker all background darker
better error page better error page
bug fixed:error when finish master/ultra mode fixed:error when finish master/ultra mode
bug fixed:shakeFX no effect when below 3 fixed:shakeFX no effect when below 3
0.8.9: 0.8.9:
invalid game when pause too much invalid game when pause too much
quick play re-added quick play re-added
new BGM:Oxygen new BGM:Oxygen(c4w&pc train)
space background little changed space background little changed
bug fixed:touch/press release with no press(don't know why) fixed:touch/press release with no press(don't know why)
0.8.8+: 0.8.8+:
fixed many fatal bugs fixed many fatal bugs
0.8.8: 0.8.8:
@@ -55,7 +65,7 @@ Future outlook:
no black side in any screen size no black side in any screen size
an unlock-all easter egg an unlock-all easter egg
cannot press invisible func key cannot press invisible func key
bugs fixed(some mode error) bugs fixed:some mode error
add many fatal bugs add many fatal bugs
0.8.7: 0.8.7:
better user experience in mode selecting better user experience in mode selecting
@@ -63,13 +73,13 @@ Future outlook:
speed of marathon mode changed speed of marathon mode changed
shorter clipboard string(when air above) shorter clipboard string(when air above)
attack system/score system little changed attack system/score system little changed
bugs fixed(rank system,some mode error when enter)(again!) bugs fixed:rank system,some mode error when enter(again!)
0.8.6: 0.8.6:
gamepad can adjust key gamepad can adjust key
add SFX when enter game add SFX when enter game
map GUI little adjusted map GUI little adjusted
event system little changed(no ctrl when scene swapping) event system little changed(no ctrl when scene swapping)
bugs fixed(rank system,some mode error when enter) bugs fixed:rank system,some mode error when enter
0.8.5-: 0.8.5-:
mode map!Brandly new GUI for mode selecting mode map!Brandly new GUI for mode selecting
mode unlock system,not that scary for noob mode unlock system,not that scary for noob

View File

@@ -84,11 +84,11 @@ local function useDefaultSet(n)
customSel[i]=customSet[n][i] customSel[i]=customSet[n][i]
end end
curBG=customRange.bg[customSel[12]] curBG=customRange.bg[customSel[12]]
BGM(customRange.bgm[customSel[13]]) BGM.play(customRange.bgm[customSel[13]])
end end
--λFuncs for widgets --λFuncs for widgets
local function SETdisp(k) local function SETval(k)
return function() return function()
return setting[k] return setting[k]
end end
@@ -156,7 +156,7 @@ local Widget={
--function()scene.push()scene.swapTo("custom")end --function()scene.push()scene.swapTo("custom")end
}, },
music={ music={
bgm= newSlider(760, 80,400,10,35,nil,SETdisp("bgm"),function(i)setting.bgm=i;BGM(bgmPlaying)end), bgm= newSlider(760, 80,400,10,35,function()BGM.freshVolume()end,SETval("bgm"),SETsto("bgm")),
up= newButton(1100, 200,120,120,C.white,55,pressKey("up")), up= newButton(1100, 200,120,120,C.white,55,pressKey("up")),
play= newButton(1100, 340,120,120,C.white,35,pressKey("space"),function()return setting.bgm==0 end), play= newButton(1100, 340,120,120,C.white,35,pressKey("space"),function()return setting.bgm==0 end),
down= newButton(1100, 480,120,120,C.white,55,pressKey("down")), down= newButton(1100, 480,120,120,C.white,55,pressKey("down")),
@@ -206,8 +206,7 @@ local Widget={
resetGameData() resetGameData()
scene.swapTo("play","none") scene.swapTo("play","none")
end), end),
sfx= newSlider(950,60,280,10,35,function()SFX("blip_1")end, SETdisp("sfx"),SETsto("sfx")), setting=newButton(1130,70,180,90,C.lightBlue,45,function()scene.push()scene.swapTo("setting_sound")end),
bgm= newSlider(950,120,280,10,35,function()BGM(bgmPlaying or"blank")end, SETdisp("bgm"),SETsto("bgm")),
quit= newButton(640,600,240,100,C.white,45,scene.back), quit= newButton(640,600,240,100,C.white,45,scene.back),
}, },
setting_game={ setting_game={
@@ -218,7 +217,7 @@ local Widget={
if setting.arr>setting.das then if setting.arr>setting.das then
setting.arr=setting.das setting.arr=setting.das
Widget.setting_game.arrD:FX() Widget.setting_game.arrD:FX()
SFX("blip_1",.4) SFX.play("blip_1",.4)
end end
end,nil,"dasU"), end,nil,"dasU"),
dasU= newButton(400,230,50,50,C.white,40,function() dasU= newButton(400,230,50,50,C.white,40,function()
@@ -226,7 +225,7 @@ local Widget={
if setting.arr>setting.das then if setting.arr>setting.das then
setting.das=setting.arr setting.das=setting.arr
Widget.setting_game.arrD:FX() Widget.setting_game.arrD:FX()
SFX("blip_1",.4) SFX.play("blip_1",.4)
end end
end,nil,"arrD"), end,nil,"arrD"),
arrD= newButton(500,230,50,50,C.white,40,function() arrD= newButton(500,230,50,50,C.white,40,function()
@@ -234,7 +233,7 @@ local Widget={
if setting.arr>setting.das then if setting.arr>setting.das then
setting.das=setting.arr setting.das=setting.arr
Widget.setting_game.dasU:FX() Widget.setting_game.dasU:FX()
SFX("blip_1",.4) SFX.play("blip_1",.4)
end end
end,nil,"arrU"), end,nil,"arrU"),
arrU= newButton(720,230,50,50,C.white,40,function() arrU= newButton(720,230,50,50,C.white,40,function()
@@ -242,18 +241,19 @@ local Widget={
if setting.arr>setting.das then if setting.arr>setting.das then
setting.das=setting.arr setting.das=setting.arr
Widget.setting_game.dasU:FX() Widget.setting_game.dasU:FX()
SFX("blip_1",.4) SFX.play("blip_1",.4)
end end
end,nil,"sddasD"), end,nil,"sddasD"),
sddasD= newButton(180,340,50,50,C.white,40, function()setting.sddas=(setting.sddas-1)%11 end, nil,"sddasU"), sddasD= newButton(180,340,50,50,C.white,40, function()setting.sddas=(setting.sddas-1)%11 end, nil,"sddasU"),
sddasU= newButton(400,340,50,50,C.white,40, function()setting.sddas=(setting.sddas+1)%11 end, nil,"sdarrD"), sddasU= newButton(400,340,50,50,C.white,40, function()setting.sddas=(setting.sddas+1)%11 end, nil,"sdarrD"),
sdarrD= newButton(500,340,50,50,C.white,40, function()setting.sdarr=(setting.sdarr-1)%4 end, nil,"sdarrU"), sdarrD= newButton(500,340,50,50,C.white,40, function()setting.sdarr=(setting.sdarr-1)%4 end, nil,"sdarrU"),
sdarrU= newButton(720,340,50,50,C.white,40, function()setting.sdarr=(setting.sdarr+1)%4 end, nil,"reTime"), sdarrU= newButton(720,340,50,50,C.white,40, function()setting.sdarr=(setting.sdarr+1)%4 end, nil,"reTime"),
reTime= newSlider(350,430,300,10,30,nil, SETdisp("reTime"), SETsto("reTime"), nil,"maxNext"), reTime= newSlider(350,430,300,10,30,nil, SETval("reTime"), SETsto("reTime"), nil,"maxNext"),
maxNext=newSlider(350,510,300,6,30,nil, SETdisp("maxNext"), SETsto("maxNext"), nil,"quickR"), maxNext=newSlider(350,510,300,6,30,nil, SETval("maxNext"), SETsto("maxNext"), nil,"autoPause"),
quickR= newSwitch(1000,430,35, SETdisp("quickR"), SETrev("quickR"), nil,"swap"), autoPause=newSwitch(350,590,20, SETval("autoPause"), SETrev("autoPause"), nil,"quickR"),
swap= newSwitch(1000,510,19, SETdisp("swap"), SETrev("swap"), nil,"fine"), quickR= newSwitch(1000,430,35, SETval("quickR"), SETrev("quickR"), nil,"swap"),
fine= newSwitch(1000,590,20, SETdisp("fine"), SETrev("fine"), nil,"ctrl"), swap= newSwitch(1000,510,19, SETval("swap"), SETrev("swap"), nil,"fine"),
fine= newSwitch(1000,590,20, SETval("fine"), SETrev("fine"), nil,"ctrl"),
ctrl= newButton(1020,230,320,80,C.white,35,function()scene.push()scene.swapTo("setting_key")end, nil,"touch"), ctrl= newButton(1020,230,320,80,C.white,35,function()scene.push()scene.swapTo("setting_key")end, nil,"touch"),
touch= newButton(1020,340,320,80,C.white,35,function()scene.push()scene.swapTo("setting_touch")end,nil,"back"), touch= newButton(1020,340,320,80,C.white,35,function()scene.push()scene.swapTo("setting_touch")end,nil,"back"),
back= newButton(1160,600,160,160,C.white,50,scene.back, nil,"graphic"), back= newButton(1160,600,160,160,C.white,50,scene.back, nil,"graphic"),
@@ -261,23 +261,23 @@ local Widget={
setting_graphic={ setting_graphic={
sound= newButton(200,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_sound")end, nil,"game"), sound= newButton(200,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_sound")end, nil,"game"),
game= newButton(1080,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_game")end, nil,"ghost"), game= newButton(1080,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_game")end, nil,"ghost"),
ghost= newSwitch(310,180,35,SETdisp("ghost"), SETrev("ghost"), nil,"center"), ghost= newSwitch(310,180,35,SETval("ghost"), SETrev("ghost"), nil,"center"),
center= newSwitch(580,180,35,SETdisp("center"), SETrev("center"), nil,"smo"), center= newSwitch(580,180,35,SETval("center"), SETrev("center"), nil,"smo"),
smo= newSwitch(310,260,25,SETdisp("smo"), SETrev("smo"), nil,"grid"), smo= newSwitch(310,260,25,SETval("smo"), SETrev("smo"), nil,"grid"),
grid= newSwitch(580,260,30,SETdisp("grid"), SETrev("grid"), nil,"dropFX"), grid= newSwitch(580,260,30,SETval("grid"), SETrev("grid"), nil,"dropFX"),
dropFX= newSlider(310,350,373,5,35,nil,SETdisp("dropFX"), SETsto("dropFX"), nil,"shakeFX"), dropFX= newSlider(310,350,373,5,35,nil,SETval("dropFX"), SETsto("dropFX"), nil,"shakeFX"),
shakeFX=newSlider(310,430,373,5,35,nil,SETdisp("shakeFX"), SETsto("shakeFX"), nil,"atkFX"), shakeFX=newSlider(310,430,373,5,35,nil,SETval("shakeFX"), SETsto("shakeFX"), nil,"atkFX"),
atkFX= newSlider(310,510,373,5,35,nil,SETdisp("atkFX"), SETsto("atkFX"), nil,"frame"), atkFX= newSlider(310,510,373,5,35,nil,SETval("atkFX"), SETsto("atkFX"), nil,"frame"),
frame= newSlider(310,590,373,10,35,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"), frame= newSlider(310,590,373,10,35,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,SETdisp("fullscreen"),function() fullscreen=newSwitch(990,180,40,SETval("fullscreen"),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(love.graphics.getWidth(),love.graphics.getHeight()) love.resize(love.graphics.getWidth(),love.graphics.getHeight())
end end
end,nil,"bg"), end,nil,"bg"),
bg= newSwitch(990,250,35,SETdisp("bg"),SETrev("bg"),nil,"bgspace"), bg= newSwitch(990,250,35,SETval("bg"),SETrev("bg"),nil,"bgspace"),
bgspace=newSwitch(990,330,35,SETdisp("bgspace"),function() bgspace=newSwitch(990,330,35,SETval("bgspace"),function()
setting.bgspace=not setting.bgspace setting.bgspace=not setting.bgspace
if setting.bgspace then if setting.bgspace then
space.new() space.new()
@@ -294,13 +294,13 @@ local Widget={
back= newButton(1160,600,160,160,C.white,50,scene.back,nil,"sound"), back= newButton(1160,600,160,160,C.white,50,scene.back,nil,"sound"),
}, },
setting_sound={ setting_sound={
game= newButton(200,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_game")end, nil,"graphic"), game= newButton(200,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_game")end, nil,"graphic"),
graphic=newButton(1080,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_graphic")end, nil,"sfx"), graphic=newButton(1080,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_graphic")end, nil,"sfx"),
sfx= newSlider(180,250,400,10,35,function()SFX("blip_1")end, SETdisp("sfx"), SETsto("sfx"), nil,"bgm"), sfx= newSlider(180,250,400,10,35,function()SFX.play("blip_1")end, SETval("sfx"), SETsto("sfx"), nil,"bgm"),
bgm= newSlider(750,250,400,10,35,function()BGM(bgmPlaying or"blank")end, SETdisp("bgm"), SETsto("bgm"), nil,"vib"), bgm= newSlider(750,250,400,10,35,function()BGM.freshVolume()end, SETval("bgm"), SETsto("bgm"), nil,"vib"),
vib= newSlider(180,440,400,5 ,35,function()VIB(1)end, SETdisp("vib"), SETsto("vib"), nil,"voc"), vib= newSlider(180,440,400,5 ,35,function()VIB(1)end, SETval("vib"), SETsto("vib"), nil,"voc"),
voc= newSlider(750,440,400,10,35,function()VOICE("nya")end, SETdisp("voc"), SETsto("voc"), nil,"stereo"), voc= newSlider(750,440,400,10,35,function()VOICE("nya")end, SETval("voc"), SETsto("voc"), nil,"stereo"),
stereo= newSlider(180,630,400,10,35,function()SFX("move",1,-1)SFX("lock",1,1)end, SETdisp("stereo"), SETsto("stereo"),function()return setting.sfx==0 end,"back"), stereo= newSlider(180,630,400,10,35,function()SFX.play("move",1,-1)SFX.play("lock",1,1)end, SETval("stereo"), SETsto("stereo"),function()return setting.sfx==0 end,"back"),
back=newButton(1160,600,160,160,C.white,50,scene.back,nil,"game"), back=newButton(1160,600,160,160,C.white,50,scene.back,nil,"game"),
}, },
setting_key={ setting_key={
@@ -364,20 +364,20 @@ local Widget={
b20= newSwitch(620,620, 35,VKAdisp(20),VKAcode(20)), b20= newSwitch(620,620, 35,VKAdisp(20),VKAcode(20)),
norm= newButton(840,100,240,80,C.white,45,function()for i=1,20 do VK_org[i].ava=i<11 end end), norm= newButton(840,100,240,80,C.white,45,function()for i=1,20 do VK_org[i].ava=i<11 end end),
pro= newButton(1120,100,240,80,C.white,35,function()for i=1,20 do VK_org[i].ava=true end end), pro= newButton(1120,100,240,80,C.white,35,function()for i=1,20 do VK_org[i].ava=true end end),
hide= newSwitch(1170,200,40,SETdisp("VKSwitch"),SETrev("VKSwitch")), hide= newSwitch(1170,200,40,SETval("VKSwitch"),SETrev("VKSwitch")),
track= newSwitch(1170,300,35,SETdisp("VKTrack"),SETrev("VKTrack")), track= newSwitch(1170,300,35,SETval("VKTrack"),SETrev("VKTrack")),
icon= newSwitch(850,300,40,SETdisp("VKIcon"),SETrev("VKIcon")), icon= newSwitch(850,300,40,SETval("VKIcon"),SETrev("VKIcon")),
tkset= newButton(1120,400,240,80,C.white,32,function() tkset= newButton(1120,400,240,80,C.white,32,function()
scene.push() scene.push()
scene.swapTo("setting_trackSetting") scene.swapTo("setting_trackSetting")
end,function()return not setting.VKTrack end), end,function()return not setting.VKTrack end),
alpha= newSlider(840,490,400,10,40,nil,SETdisp("VKAlpha"),SETsto("VKAlpha")), alpha= newSlider(840,490,400,10,40,nil,SETval("VKAlpha"),SETsto("VKAlpha")),
back= newButton(1100,600,240,80,C.white,45,scene.back), back= newButton(1100,600,240,80,C.white,45,scene.back),
}, },
setting_trackSetting={ setting_trackSetting={
VKDodge=newSwitch(400,200, 35,SETdisp("VKDodge"),SETrev("VKDodge")), VKDodge=newSwitch(400,200, 35,SETval("VKDodge"),SETrev("VKDodge")),
VKTchW= newSlider(140,310,1000,10,35,nil,SETdisp("VKTchW"),function(i)setting.VKTchW=i;setting.VKCurW=math.max(setting.VKCurW,i)end), VKTchW= newSlider(140,310,1000,10,35,nil,SETval("VKTchW"),function(i)setting.VKTchW=i;setting.VKCurW=math.max(setting.VKCurW,i)end),
VKCurW= newSlider(140,370,1000,10,35,nil,SETdisp("VKCurW"),function(i)setting.VKCurW=i;setting.VKTchW=math.min(setting.VKTchW,i)end), VKCurW= newSlider(140,370,1000,10,35,nil,SETval("VKCurW"),function(i)setting.VKCurW=i;setting.VKTchW=math.min(setting.VKTchW,i)end),
back= newButton(1080,600,240,80,C.white,45,scene.back), back= newButton(1080,600,240,80,C.white,45,scene.back),
}, },
help={ help={