Compare commits

...

8 Commits

Author SHA1 Message Date
MrZ626
55a1bd06f3 版本推进 2021-11-24 06:41:51 +08:00
MrZ626
6a29abf7f0 自定义hold数量为0时不显示hold模式选择器,顺便更新创建房间参数ui遗漏 close #483 2021-11-23 22:30:43 +08:00
MrZ626
83bdd9f2c4 【警告:可能有bug,需要测试】
较大规模整理玩家相关代码
较大规模整理玩家相关代码,重构出块延迟和消行延迟逻辑,现在0是真的无延迟,不再有1帧等待了
添加出块延迟打断(即ARE打断)(不包括消行延迟,默认为打断至无穷大,相当于无此功能)
自定义游戏和自定义房间ui跟进
close #471
2021-11-23 20:26:31 +08:00
MrZ626
95879827c8 调整游戏大logo为正体字 2021-11-23 18:13:45 +08:00
MrZ626
2ade518207 调整tip 2021-11-23 00:48:49 +08:00
MrZ626
36c8449e4d 内存过低的提示每次启动最多出现三次 2021-11-23 00:28:08 +08:00
MrZ626
3c04df69f3 移除手柄时自动松开所有按下了的键,整理代码 2021-11-23 00:27:57 +08:00
MrZ626
1224ee9a67 词典的新人引导条目链接向user670的翻译版本 close #482 2021-11-22 23:45:54 +08:00
26 changed files with 581 additions and 561 deletions

View File

@@ -298,6 +298,15 @@ local jsAxisEventName={
triggerleft='triggerleft',
triggerright='triggerright'
}
local gamePadKeys={'a','b','x','y','back','guide','start','leftstick','rightstick','leftshoulder','rightshoulder','dpup','dpdown','dpleft','dpright'}
local dPadToKey={
dpup='up',
dpdown='down',
dpleft='left',
dpright='right',
start='return',
back='escape',
}
function love.joystickadded(JS)
jsState[JS:getID()]={
_loveJSObj=JS,
@@ -310,6 +319,11 @@ end
function love.joystickremoved(JS)
local js=jsState[JS:getID()]
if js then
for i=1,#gamePadKeys do
if JS:isGamepadDown(gamePadKeys[i])then
love.gamepadreleased(JS,gamePadKeys[i])
end
end
love.gamepadaxis(JS,'leftx',0)
love.gamepadaxis(JS,'lefty',0)
love.gamepadaxis(JS,'rightx',0)
@@ -320,7 +334,6 @@ function love.joystickremoved(JS)
MES.new('info',"Joystick removed")
end
end
function love.gamepadaxis(JS,axis,val)
local js=jsState[JS:getID()]
if js then
@@ -355,15 +368,6 @@ function love.gamepadaxis(JS,axis,val)
end
end
end
local dPadToKey={
dpup='up',
dpdown='down',
dpleft='left',
dpright='right',
start='return',
back='escape',
}
function love.gamepadpressed(_,i)
mouseShow=false
if SCN.swapping then return end
@@ -384,11 +388,11 @@ end
function love.directorydropped(dir)
if SCN.directoryDropped then SCN.directoryDropped(dir)end
end
local lastGCtime=0
local autoGCcount=0
function love.lowmemory()
if love.timer.getTime()-lastGCtime>6.26 then
collectgarbage()
lastGCtime=love.timer.getTime()
collectgarbage()
if autoGCcount<3 then
autoGCcount=autoGCcount+1
MES.new('check',"[auto GC] low MEM 设备内存过低")
end
end

View File

@@ -61,7 +61,7 @@ function back.draw()
gc_setLineWidth(6)
gc_setColor(.8,.9,1,.3)
for i=1,8 do gc_polygon('line',SVG_TITLE_FAN[i])end
for i=1,#SVG_TITLE_FAN do gc_polygon('line',SVG_TITLE_FAN[i])end
gc_setLineWidth(2)
gc_setColor(1,.5,.7,.3)

View File

@@ -12,7 +12,7 @@ local baseBot={
function baseBot.update(bot)
local P=bot.P
local keys=bot.keys
if P.control and P.waiting==-1 then
if P.control and P.waiting==0 then
bot.delay=bot.delay-1
if not keys[1]then
if bot.runningThread then

View File

@@ -6,6 +6,8 @@ return{
lock=1e99,
wait=0,
fall=0,
hang=5,
hurry=1e99,
--Control
nextCount=6,
@@ -13,7 +15,6 @@ return{
holdCount=1,
infHold=true,
phyHold=false,
hang=5,
--Visual
bone=false,

View File

@@ -20,140 +20,129 @@ RANK_COLORS={
{1,.5,.4},
{.95,.5,.95},
}
do--SVG_TITLE
SVG_TITLE={
do--SVG_TITLE_FILL, SVG_TITLE_LINE
SVG_TITLE_FILL={
{
53, 60,
1035, 0,
964, 218,
660, 218,
391, 1300,
231, 1154,
415, 218,
0, 218,
0,0,
0,34,
63,34,
63,227,
97,227,
97,34,
160,34,
160,0,
},
{
716, 290,
1429, 290,
1312, 462,
875, 489,
821, 695,
1148, 712,
1017, 902,
761, 924,
707, 1127,
1106, 1101,
1198, 1300,
465, 1300,
126,60,
244,60,
244,94,
160,94,
160,127,
230,127,
230,161,
160,161,
160,194,
244,194,
244,227,
126,227,
},
{
1516, 287,
2102, 290,
2036, 464,
1598, 465,
1322, 905,
1395, 1102,
1819, 1064,
1743, 1280,
1286, 1310,
1106, 902,
262,82,
283,60,
385,60,
385,94,
296,94,
296,194,
385,194,
385,227,
283,227,
262,206,
},
{
2179, 290,
2411, 290,
2272, 688,
2674, 666,
2801, 290,
3041, 290,
2693, 1280,
2464, 1280,
2601, 879,
2199, 897,
2056, 1280,
1828, 1280,
404,60,
437,60,
437,127,
505,127,
505,60,
538,60,
538,227,
505,227,
505,161,
437,161,
437,227,
404,227,
},
{
3123, 290,
3480, 290,
3496, 480,
3664, 290,
4017, 294,
3682, 1280,
3453, 1280,
3697, 578,
3458, 843,
3304, 842,
3251, 561,
3001, 1280,
2779, 1280,
558,60,
604,60,
640,153,
676,60,
722,60,
722,227,
688,227,
688,108,
655,194,
625,194,
591,108,
591,227,
558,227,
},
{
4088, 290,
4677, 290,
4599, 501,
4426, 502,
4219, 1069,
4388, 1070,
4317, 1280,
3753, 1280,
3822, 1068,
3978, 1068,
4194, 504,
4016, 504,
743,60,
777,60,
777,227,
743,227,
},
{
4747, 290,
4978, 295,
4921, 464,
5186, 850,
5366, 290,
5599, 295,
5288, 1280,
5051, 1280,
5106, 1102,
4836, 709,
4641, 1280,
4406, 1280,
798,60,
831,60,
899,173,
899,60,
933,60,
933,227,
899,227,
831,115,
831,227,
798,227,
},
{
5814, 290,
6370, 295,
6471, 415,
6238, 1156,
6058, 1280,
5507, 1280,
5404, 1154,
5635, 416,
-- 5814, 290,
-- 5878, 463,
5770, 542,
5617, 1030,
5676, 1105,
5995, 1106,
6100, 1029,
6255, 541,
6199, 465,
5878, 463,
950,82,
971,60,
1064,60,
1085,82,
1085,206,
1064,227,
971,227,
950,206,
950,82,
984,94,
984,194,
1051,194,
1051,94,
984,94,
},
}
for _,C in next,SVG_TITLE do
for _,C in next,SVG_TITLE_FILL do
for i=1,#C do
C[i]=C[i]*.1626
C[i]=C[i]*.94
end
end
SVG_TITLE_LINE=TABLE.shift(SVG_TITLE_FILL)
SVG_TITLE_LINE[8],SVG_TITLE_LINE[9]={},{}
for j=1,16 do SVG_TITLE_LINE[8][j]=SVG_TITLE_FILL[8][j]end
for j=19,#SVG_TITLE_FILL[8]-2 do SVG_TITLE_LINE[9][j-18]=SVG_TITLE_FILL[8][j]end
end
do--SVG_TITLE_FAN
SVG_TITLE_FAN={}
local sin,cos=math.sin,math.cos
for i=1,8 do
local L={}
for i=1,9 do
local L=TABLE.copy(SVG_TITLE_LINE[i])
SVG_TITLE_FAN[i]=L
for j=1,#SVG_TITLE[i]do
L[j]=SVG_TITLE[i][j]
end
for j=1,#L,2 do
local x,y=L[j],L[j+1]--0<x<3041, 290<y<1280
x,y=-(x+240+y*.3)*.002,(y-580)*.9
local x,y=L[j],L[j+1]--0<x<988, 290<y<1280
x,y=-(x+280)*.002,(y-580)*.9--X=ang, Y=dist
x,y=y*cos(x),-y*sin(x)--Rec-Pol-Rec
L[j],L[j+1]=x,y+300
end
@@ -547,13 +536,12 @@ do--Game data tables
ROOMENV={
--Room config
capacity=10,
FTLock=true,
--Basic
drop=30,
lock=60,
wait=0,
fall=0,
FTLock=true,
drop=30,lock=60,
wait=0,fall=0,
hang=5,hurry=1e99,
--Control
nextCount=6,

View File

@@ -16,8 +16,8 @@ return{
{"To New Players",
"guide newbie noob",
"help",
"To new players that want to get better at the game:\n\tTwo principles:\n\t1. find a version with good controls (e.g. Techmino, Tetr.io, Tetris Online, Jstris, Tetr.js). Do not use those version used for programming practice.\n\t2. Build foundations in your skills (stable Techrashes using next queue to aid decisions), don't go for fancy T-Spins from the start.\n\n\tTwo main techniques:\n\t1. familiarize yourself with spawn locations of pieces, and the controls to move the piece into each location\n\t2. Plan ahead of where to put the pieces\nHere is a article written by a well-known player in Chinese Tetris community talking about advices to new players. Click the globe if you can read simplified Chinese.",
"https://bilibili.com/read/cv2352939",
"To new players that want to get better at the game:\n\tTwo principles:\n\t1. find a version with good controls (e.g. Techmino, Tetr.io, Tetris Online, Jstris, Tetr.js). Do not use those version used for programming practice.\n\t2. Build foundations in your skills (stable Techrashes using next queue to aid decisions), don't go for fancy T-Spins from the start.\n\n\tTwo main techniques:\n\t1. familiarize yourself with spawn locations of pieces, and the controls to move the piece into each location\n\t2. Plan ahead of where to put the pieces\nHere is a article written by a well-known player in Chinese Tetris community talking about advices to new players. Click the globe to read the translated article by User670.",
"https://github.com/user670/temp/blob/master/tips_to_those_new_to_top.md",
},
{"Learning T-spins",
"tspin learning study guide tips",

View File

@@ -296,6 +296,8 @@ return{
lock="Lock Delay",
wait="Entry Delay",
fall="Line Delay",
hang="Death Delay",
hurry="ARE Interruption",
capacity="Capacity",
create="Create",
@@ -480,6 +482,7 @@ return{
wait="Entry Delay",
fall="Line Delay",
hang="Death Delay",
hurry="ARE Interruption",
bg="Background",
bgm="Music",

View File

@@ -262,6 +262,8 @@ return{
lock="Retraso de Bloqueo",
wait="Retraso de Spawneo",
fall="Retraso de Línea",
-- hang="Death Delay",
-- hurry="ARE Interruption",
capacity="Capacidad",
create="Crear",
@@ -445,6 +447,7 @@ return{
wait="Retraso de Spawneo",
fall="Retraso de Línea",
-- hang="Death Delay",
-- hurry="ARE Interruption",
bg="Fondo",
bgm="Música",

View File

@@ -258,6 +258,8 @@ return{
lock="Délai de verrouillage",
wait="Délai d'apparition",
fall="Délai de ligne",
-- hang="Death Delay",
-- hurry="ARE Interruption",
-- capacity="Capacity",
-- create="Create",
@@ -446,6 +448,7 @@ return{
wait="Délai d'apparition",
fall="Délai de ligne",
-- hang="Death Delay",
-- hurry="ARE Interruption",
bg="Arrière-plan",
bgm="Musique",

View File

@@ -284,6 +284,8 @@ return{
lock="Delay Trava",
wait="Delay Entrada",
fall="Delay Linha",
-- hang="Death Delay",
-- hurry="ARE Interruption",
-- capacity="Capacity",
-- create="Create",
@@ -468,6 +470,7 @@ return{
wait="Delay Entrada",
fall="Delay Linha",
-- hang="Death Delay",
-- hurry="ARE Interruption",
bg="Fundo",
bgm="Música",

View File

@@ -190,6 +190,8 @@ return{
lock="↓_",
wait="→=",
fall="↓=",
hang=":(=",
hurry="_x",
capacity="<0/?>",
create=">",
@@ -373,6 +375,7 @@ return{
wait="→=",
fall="↓=",
hang=":(=",
hurry="_x",
bg="{~}",
bgm="(~)",

View File

@@ -296,6 +296,8 @@ return{
lock="锁定延迟",
wait="出块等待",
fall="消行延迟",
hang="窒息延迟",
hurry="ARE打断",
capacity="房间容量",
create="创建",
@@ -479,6 +481,7 @@ return{
wait="出块等待",
fall="消行延迟",
hang="窒息延迟",
hurry="ARE打断",
bg="背景",
bgm="音乐",
@@ -905,7 +908,7 @@ return{
"快去打一把100%极简看看会怎样",
"锟斤拷锟斤拷锟斤拷",
"来学编程,好玩的",
"老牌益智游戏了属于是",
"老牌益智游戏了",
"连续pc有大量知识要背不过背出来后随手10连pc不是问题",
"六连块总共有……?那不重要,不会做的(大概",
"论如何正确使用Unicode私用区定制字体",
@@ -927,13 +930,13 @@ return{
"你们考虑过Z酱的感受吗没有你们只考虑你自己。",
"你说彩蛋?嗯…算是有,可以找找",
"你有一个好",
"你知道吗:看主页机器人玩可能比较费电",
"你知道吗:全程不使用任何旋转键完成40行模式是有可能的",
"你知道吗:全程不使用左右移动键完成40行模式是有可能的",
"你知道吗:停留在模式地图界面很费电",
"你知道吗:在其他(方块)游戏相关场合提及本游戏是很不礼貌的",
"你知道吗:O-Spin是在0.8.20 (Fantastic Global Update II)中诞生的",
"你知道吗:TRS旋转系统的最初形态在0.0.091726版本就存在了",
"你知道吗[001]看主页机器人玩可能比较费电",
"你知道吗[002]全程不使用任何旋转键完成40行模式是有可能的",
"你知道吗[003]全程不使用左右移动键完成40行模式是有可能的",
"你知道吗[004]停留在模式地图界面很费电",
"你知道吗[005]在其他(方块)游戏相关场合提及本游戏是很不礼貌的",
"你知道吗[006]O-Spin是在0.8.20 (Fantastic Global Update II)中诞生的",
"你知道吗[007]TRS旋转系统的最初形态在0.0.091726版本就存在了",
"你准备好了吗?",
"其实很多时候“吃键”是玩家对游戏机制不了解或者自己的操作问题导致的",
"其实S和Z有四个方向(状态),虽然看起来只有两个",
@@ -967,8 +970,9 @@ return{
"时间碎片[013] V0.14.4加入第一首不是用Beepbox制作的BGM",
"时间碎片[014] V0.14.5加入第一首社区玩家自制BGM",
"时间碎片[015] V0.15.5加入录像回放菜单",
"时间碎片[016] V0.16.0应该是单次更新内容",
"时间碎片[016] V0.16.0应该是单次更新内容最多的(起码更新历史最长)",
"时间碎片[017] V0.16.2加入打击垫样式的音效室",
"时间碎片[018] V0.17.0加入手柄的摇杆和扳机支持",
"使用固定堆叠方法达成20TSD难度很低",
"试试用跳舞毯打块",
"适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活",
@@ -1058,18 +1062,18 @@ return{
"e^(πi)=-1",
"e^(πi/2)=i",
"e^(πi/4)=(1+i)/√2",
"Farter:“成天被夸赞‘好玩’的”",
"Farter:“可以形成方块圈子小中心话题,同作者一起衍生一些概念与梗的”",
"Farter:“论方块的软工意义(就算这么小个范围内,各种取舍蒙混翻车现象都总会以很易懂的方式出现(”",
"Farter:“民间微创新”",
"Farter:“民间音lè与图案”",
"Farter:“民间游戏设计”",
"Farter:“是方块爱好者研究平台”",
"Farter:“是方块萌新入坑接收器”",
"Farter:“是居家旅行装逼必备”",
"Farter:“是民间UI动效艺术作品”",
"Farter:“是一滩散乱的代码组成的蜜汁结构”",
"Farter:“它是现在的techmino已发布版本”",
"Farter评[01]“成天被夸赞‘好玩’的”",
"Farter评[02]“可以形成方块圈子小中心话题,同作者一起衍生一些概念与梗的”",
"Farter评[03]“论方块的软工意义(就算这么小个范围内,各种取舍蒙混翻车现象都总会以很易懂的方式出现(”",
"Farter评[04]“民间微创新”",
"Farter评[05]“民间音lè与图案”",
"Farter评[06]“民间游戏设计”",
"Farter评[07]“是方块爱好者研究平台”",
"Farter评[08]“是方块萌新入坑接收器”",
"Farter评[09]“是居家旅行装逼必备”",
"Farter评[10]“是民间UI动效艺术作品”",
"Farter评[11]“是一滩散乱的代码组成的蜜汁结构”",
"Farter评[12]“它是现在的techmino已发布版本”",
"fin neo iso 是满足tspin条件的特殊t2的名字",
"git commit",
"git push -f",

View File

@@ -294,6 +294,8 @@ return{
lock="锁定延迟",
wait="进入延迟",
fall="线路延迟",
hang="毁灭延迟",
hurry="是打扰吗",
capacity="容量",
create="创造",
@@ -477,6 +479,7 @@ return{
wait="进入延迟",
fall="线路延迟",
hang="毁灭延迟",
hurry="是打扰吗",
bg="背景",
bgm="音乐",
@@ -753,7 +756,7 @@ return{
['infinite_dig']= {"无限:挖掘", "", "挖,挖,挖"},
['marathon_inf']= {"马拉松", "无尽", "无尽马拉松"},
['custom_clear']= {"习俗", "正常"} ,
['custom_clear']= {"习俗", "正常"},
['custom_puzzle']= {"习俗", "令人费解的"},
},
}

View File

@@ -295,6 +295,8 @@ return{
lock="鎖定延遲",
wait="方塊生成等待",
fall="行清除延遲",
hang="死亡延遲",
hurry="ARE打斷",
capacity="房間容量",
create="創建",
@@ -478,6 +480,7 @@ return{
wait="方塊生成等待",
fall="行清除延遲",
hang="死亡延遲",
hurry="ARE打斷",
bg="背景",
bgm="音樂",

View File

@@ -170,7 +170,7 @@ local function _drawField(P,showInvis)
local V,F=P.visTime,P.field
local start=int((P.fieldBeneath+P.fieldUp)/30+1)
local texture=P.skinLib
if P.falling==-1 then--Blocks only
if P.falling==0 then--Blocks only
if ENV.upEdge then
gc_setShader(shader_lighter)
gc_translate(0,-4)
@@ -782,7 +782,7 @@ function draw.norm(P,repMode)
_drawFXs(P)
--Draw current block
if P.cur and P.waiting==-1 then
if P.cur and P.waiting==0 then
local C=P.cur
local curColor=C.color
@@ -997,7 +997,7 @@ function draw.demo(P)
gc_translate(0,600)
_drawField(P)
_drawFXs(P)
if P.cur and P.waiting==-1 then
if P.cur and P.waiting==0 then
if ENV.ghost then
drawGhost[ENV.ghostType](P.cur.bk,P.curX,P.ghoY,ENV.ghost,P.skinLib,curColor)
end

View File

@@ -3,7 +3,6 @@ return{
dascut=0,dropcut=0,
sddas=2,sdarr=2,
ihs=true,irs=true,ims=true,
hang=5,FTLock=true,
ghostType='gray',
block=true,ghost=.3,center=1,
@@ -30,6 +29,7 @@ return{
drop=60,lock=60,
wait=0,fall=0,
hang=5,hurry=1e99,
bone=false,
lockout=false,
fieldH=20,heightLimit=1e99,
@@ -69,4 +69,5 @@ return{
bg='none',bgm='race',
allowMod=true,
FTLock=true,
}

View File

@@ -36,54 +36,6 @@ local function _getNewStatTable()
end
return T
end
local playerActions={
Player.act_moveLeft, --1
Player.act_moveRight, --2
Player.act_rotRight, --3
Player.act_rotLeft, --4
Player.act_rot180, --5
Player.act_hardDrop, --6
Player.act_softDrop, --7
Player.act_hold, --8
Player.act_func1, --9
Player.act_func2, --10
Player.act_insLeft, --11
Player.act_insRight, --12
Player.act_insDown, --13
Player.act_down1, --14
Player.act_down4, --15
Player.act_down10, --16
Player.act_dropLeft, --17
Player.act_dropRight, --18
Player.act_zangiLeft, --19
Player.act_zangiRight,--20
}
local function _pressKey(P,keyID)
if P.keyAvailable[keyID]and P.alive then
P.keyPressing[keyID]=true
playerActions[keyID](P)
P.stat.key=P.stat.key+1
end
end
local function _releaseKey(P,keyID)
P.keyPressing[keyID]=false
end
local function _pressKey_Rec(P,keyID)
if P.keyAvailable[keyID]and P.alive then
local L=GAME.rep
ins(L,P.frameRun)
ins(L,keyID)
P.keyPressing[keyID]=true
playerActions[keyID](P)
P.stat.key=P.stat.key+1
end
end
local function _releaseKey_Rec(P,keyID)
local L=GAME.rep
ins(L,P.frameRun)
ins(L,32+keyID)
P.keyPressing[keyID]=false
end
local function _newEmptyPlayer(id,mini)
local P={id=id}
PLAYERS[id]=P
@@ -92,15 +44,6 @@ local function _newEmptyPlayer(id,mini)
--Inherit functions of Player class
for k,v in next,Player do P[k]=v end
--Set key/timer event
if P.id==1 and GAME.recording then
P.pressKey=_pressKey_Rec
P.releaseKey=_releaseKey_Rec
else
P.pressKey=_pressKey
P.releaseKey=_releaseKey
end
--Field position
P.swingOffset={--Shake FX
x=0,y=0,
@@ -195,7 +138,7 @@ local function _newEmptyPlayer(id,mini)
]]
P.movDir,P.moving,P.downing=0,0,0--Last move key,DAS charging,downDAS charging
P.dropDelay,P.lockDelay=0,0
P.waiting,P.falling=-1,-1
P.waiting,P.falling=0,0
P.freshTime=0
P.spinLast=false
P.ctrlCount=0--Key press time, for finesse check

View File

@@ -200,7 +200,301 @@ function Player:createBeam(R,send)
end
--------------------------</FX>--------------------------
--------------------------<Action>--------------------------
function Player:act_moveLeft(auto)
if not auto then
self.ctrlCount=self.ctrlCount+1
end
self.movDir=-1
if self.control and self.waiting==0 then
if self.cur and not self:ifoverlap(self.cur.bk,self.curX-1,self.curY)then
self:createMoveFX('left')
self.curX=self.curX-1
self:freshBlock('move')
if not auto then
self.moving=0
end
self.spinLast=false
else
self.moving=self.gameEnv.das
end
else
self.moving=0
end
end
function Player:act_moveRight(auto)
if not auto then
self.ctrlCount=self.ctrlCount+1
end
self.movDir=1
if self.control and self.waiting==0 then
if self.cur and not self:ifoverlap(self.cur.bk,self.curX+1,self.curY)then
self:createMoveFX('right')
self.curX=self.curX+1
self:freshBlock('move')
if not auto then
self.moving=0
end
self.spinLast=false
else
self.moving=self.gameEnv.das
end
else
self.moving=0
end
end
function Player:act_rotRight()
if self.control and self.waiting==0 and self.cur then
self.ctrlCount=self.ctrlCount+1
self:spin(1)
self.keyPressing[3]=false
end
end
function Player:act_rotLeft()
if self.control and self.waiting==0 and self.cur then
self.ctrlCount=self.ctrlCount+1
self:spin(3)
self.keyPressing[4]=false
end
end
function Player:act_rot180()
if self.control and self.waiting==0 and self.cur then
self.ctrlCount=self.ctrlCount+2
self:spin(2)
self.keyPressing[5]=false
end
end
function Player:act_hardDrop()
local ENV=self.gameEnv
if self.control and self.waiting==0 and self.cur then
if self.lastPiece.autoLock and self.frameRun-self.lastPiece.frame<ENV.dropcut then
SFX.play('drop_cancel',.3)
else
if self.curY>self.ghoY then
self:createDropFX()
self.curY=self.ghoY
self.spinLast=false
if self.sound then
SFX.play('drop',nil,self:getCenterX()*.15)
if SETTING.vib>0 then VIB(SETTING.vib+1)end
end
end
if ENV.shakeFX then
self.swingOffset.vy=.6
self.swingOffset.va=self.swingOffset.va+self:getCenterX()*6e-4
end
self.lockDelay=-1
self.keyPressing[6]=false
self:drop()
end
end
end
function Player:act_softDrop()
local ENV=self.gameEnv
self.downing=1
if self.control and self.waiting==0 and self.cur then
if self.curY>self.ghoY then
self.curY=self.curY-1
self:freshBlock('fresh')
self.spinLast=false
self:checkTouchSound()
elseif ENV.deepDrop then
local CB=self.cur.bk
local y=self.curY-1
while self:ifoverlap(CB,self.curX,y)and y>0 do
y=y-1
end
if y>0 then
self.ghoY=y
self:createDropFX()
self.curY=y
self:freshBlock('move')
SFX.play('swipe')
end
end
end
end
function Player:act_hold()
if self.control and self.waiting==0 then
self:hold()
self.keyPressing[8]=false
end
end
function Player:act_func1()
self.gameEnv.fkey1(self)
end
function Player:act_func2()
self.gameEnv.fkey2(self)
end
function Player:act_insLeft(auto)
if not self.cur then
return
end
local x0=self.curX
while not self:ifoverlap(self.cur.bk,self.curX-1,self.curY)do
self:createMoveFX('left')
self.curX=self.curX-1
self:freshBlock('move',true)
end
if self.curX~=x0 then
self.spinLast=false
self:checkTouchSound()
end
if self.gameEnv.shakeFX then
self.swingOffset.vx=-1.5
end
if auto then
if self.ctrlCount==0 then
self.ctrlCount=1
end
else
self.ctrlCount=self.ctrlCount+1
end
end
function Player:act_insRight(auto)
if not self.cur then
return
end
local x0=self.curX
while not self:ifoverlap(self.cur.bk,self.curX+1,self.curY)do
self:createMoveFX('right')
self.curX=self.curX+1
self:freshBlock('move',true)
end
if self.curX~=x0 then
self.spinLast=false
self:checkTouchSound()
end
if self.gameEnv.shakeFX then
self.swingOffset.vx=1.5
end
if auto then
if self.ctrlCount==0 then
self.ctrlCount=1
end
else
self.ctrlCount=self.ctrlCount+1
end
end
function Player:act_insDown()
if self.cur and self.curY>self.ghoY then
local ENV=self.gameEnv
self:createDropFX()
if ENV.shakeFX then
self.swingOffset.vy=.5
end
self.curY=self.ghoY
self.lockDelay=ENV.lock
self.spinLast=false
self:freshBlock('fresh')
self:checkTouchSound()
end
end
function Player:act_down1()
if self.cur and self.curY>self.ghoY then
self:createMoveFX('down')
self.curY=self.curY-1
self:freshBlock('fresh')
self.spinLast=false
end
end
function Player:act_down4()
if self.cur and self.curY>self.ghoY then
local ghoY0=self.ghoY
self.ghoY=max(self.curY-4,self.ghoY)
self:createDropFX()
self.curY,self.ghoY=self.ghoY,ghoY0
self:freshBlock('fresh')
self.spinLast=false
end
end
function Player:act_down10()
if self.cur and self.curY>self.ghoY then
local ghoY0=self.ghoY
self.ghoY=max(self.curY-10,self.ghoY)
self:createDropFX()
self.curY,self.ghoY=self.ghoY,ghoY0
self:freshBlock('fresh')
self.spinLast=false
end
end
function Player:act_dropLeft()
if self.cur then
self:act_insLeft()
self:act_hardDrop()
end
end
function Player:act_dropRight()
if self.cur then
self:act_insRight()
self:act_hardDrop()
end
end
function Player:act_zangiLeft()
if self.cur then
self:act_insLeft()
self:act_insDown()
self:act_insRight()
self:act_hardDrop()
end
end
function Player:act_zangiRight()
if self.cur then
self:act_insRight()
self:act_insDown()
self:act_insLeft()
self:act_hardDrop()
end
end
--------------------------</Action>--------------------------
--------------------------<Method>--------------------------
local playerActions={
Player.act_moveLeft, --1
Player.act_moveRight, --2
Player.act_rotRight, --3
Player.act_rotLeft, --4
Player.act_rot180, --5
Player.act_hardDrop, --6
Player.act_softDrop, --7
Player.act_hold, --8
Player.act_func1, --9
Player.act_func2, --10
Player.act_insLeft, --11
Player.act_insRight, --12
Player.act_insDown, --13
Player.act_down1, --14
Player.act_down4, --15
Player.act_down10, --16
Player.act_dropLeft, --17
Player.act_dropRight, --18
Player.act_zangiLeft, --19
Player.act_zangiRight,--20
}function Player:pressKey(keyID)
if self.keyAvailable[keyID]and self.alive then
if self.waiting>self.gameEnv.hurry then
self.waiting=self.gameEnv.hurry
if self.waiting==0 then self:popNext()end
end
self.keyPressing[keyID]=true
playerActions[keyID](self)
self.stat.key=self.stat.key+1
if self.id==1 and GAME.recording then
local L=GAME.rep
ins(L,self.frameRun)
ins(L,keyID)
end
end
end
function Player:releaseKey(keyID)
self.keyPressing[keyID]=false
if self.id==1 and GAME.recording then
local L=GAME.rep
ins(L,self.frameRun)
ins(L,32+keyID)
end
end
function Player:newTask(code,...)
local thread=coroutine.create(code)
assert(resume(thread,self,...))
@@ -719,6 +1013,16 @@ function Player:_removeClearedLines()
FREEROW.discard(rem(self.visTime,h))
end
end
function Player:_updateFalling(val)
self.falling=val
if self.falling==0 then
local L=#self.clearingRow
if self.sound and self.gameEnv.fall>0 and #self.field+L>self.clearingRow[L]then
SFX.play('fall')
end
TABLE.cut(self.clearingRow)
end
end
function Player:removeTopClearingFX()
for i=#self.clearingRow,1,-1 do
if self.clearingRow[i]>#self.field then
@@ -728,7 +1032,7 @@ function Player:removeTopClearingFX()
end
end
if self.clearingRow[1]then
self.falling=self.gameEnv.fall
self:_updateFalling(self.gameEnv.fall)
return false
else
return true
@@ -1004,7 +1308,7 @@ function Player:hold_swap(ifpre)
self.stat.hold=self.stat.hold+1
end
function Player:hold(ifpre)
if self.holdTime>0 and(ifpre or self.waiting==-1)then
if self.holdTime>0 and(ifpre or self.waiting==0)then
if self.gameEnv.holdMode=='hold'then
self:hold_norm(ifpre)
elseif self.gameEnv.holdMode=='swap'then
@@ -1039,9 +1343,9 @@ function Player:popNext(ifhold)--Pop nextQueue to hand
self.spinLast=false
self.ctrlCount=0
self.cur=rem(self.nextQueue,1)
self.newNext()
if self.cur then
if self.nextQueue[1]then
self.cur=rem(self.nextQueue,1)
self.newNext()
self.pieceCount=self.pieceCount+1
local pressing=self.keyPressing
@@ -1251,8 +1555,6 @@ do
piece.centX,piece.centY=self.curX+sc[2],self.curY+sc[1]
piece.frame,piece.autoLock=self.frameRun,autoLock
self.waiting=ENV.wait
--Tri-corner spin check
if self.spinLast then
if C.id<6 then
@@ -1637,6 +1939,9 @@ do
end
end
--Fresh ARE
self.waiting=ENV.wait
--Prevent sudden death if hang>0
if ENV.hang>ENV.wait and self.nextQueue[1]then
local B=self.nextQueue[1]
@@ -1699,6 +2004,8 @@ do
else
self:_triggerEvent('hook_drop')
end
if self.waiting==0 then self:popNext()end
end
function Player:clearFilledLines(start,height)
@@ -1708,7 +2015,7 @@ do
self:showText(text.clear[min(_cc,21)],0,0,75,'beat',.4)
if _cc>6 then self:showText(text.cleared:gsub("$1",_cc),0,55,30,'zoomout',.4)end
self:_removeClearedLines()
self.falling=self.gameEnv.fall
self:_updateFalling(self.gameEnv.fall)
self.stat.row=self.stat.row+_cc
self.stat.dig=self.stat.dig+_gbcc
self.stat.score=self.stat.score+clearSCR[_cc]
@@ -2014,7 +2321,7 @@ local function update_alive(P)
if P.movDir~=0 then
local das,arr=ENV.das,ENV.arr
local mov=P.moving
if P.waiting==-1 then
if P.waiting==0 then
if P.movDir==1 then
if P.keyPressing[2]then
if arr>0 then
@@ -2099,25 +2406,19 @@ local function update_alive(P)
end
--Falling animation
if P.falling>=0 then
P.falling=P.falling-1
if P.falling>=0 then
if P.falling>0 then
P:_updateFalling(P.falling-1)
if P.falling>0 then
goto THROW_stop
else
local L=#P.clearingRow
if P.sound and ENV.fall>0 and #P.field+L>P.clearingRow[L]then
SFX.play('fall')
end
P.clearingRow={}
end
end
--Update block state
if P.control then
--Try spawn new block
if P.waiting>=0 then
if P.waiting>0 then
P.waiting=P.waiting-1
if P.waiting<0 then
if P.waiting<=0 then
P:popNext()
end
goto THROW_stop
@@ -2238,15 +2539,8 @@ local function update_dead(P)
P.swappingAtkMode=min(P.swappingAtkMode+2,30)
end
if P.falling>=0 then
P.falling=P.falling-1
if P.falling<0 then
local L=#P.clearingRow
if P.sound and P.gameEnv.fall>0 and #P.field+L>P.clearingRow[L]then
SFX.play('fall')
end
P.clearingRow={}
end
if P.falling>0 then
P:_updateFalling(P.falling-1)
end
if P.b2b1>0 then
P.b2b1=max(0,P.b2b1*.92-1)
@@ -2466,254 +2760,4 @@ function Player:lose(force)
end
--------------------------<\Event>--------------------------
--------------------------<Action>--------------------------
function Player:act_moveLeft(auto)
if not auto then
self.ctrlCount=self.ctrlCount+1
end
self.movDir=-1
if self.control and self.waiting==-1 then
if self.cur and not self:ifoverlap(self.cur.bk,self.curX-1,self.curY)then
self:createMoveFX('left')
self.curX=self.curX-1
self:freshBlock('move')
if not auto then
self.moving=0
end
self.spinLast=false
else
self.moving=self.gameEnv.das
end
else
self.moving=0
end
end
function Player:act_moveRight(auto)
if not auto then
self.ctrlCount=self.ctrlCount+1
end
self.movDir=1
if self.control and self.waiting==-1 then
if self.cur and not self:ifoverlap(self.cur.bk,self.curX+1,self.curY)then
self:createMoveFX('right')
self.curX=self.curX+1
self:freshBlock('move')
if not auto then
self.moving=0
end
self.spinLast=false
else
self.moving=self.gameEnv.das
end
else
self.moving=0
end
end
function Player:act_rotRight()
if self.control and self.waiting==-1 and self.cur then
self.ctrlCount=self.ctrlCount+1
self:spin(1)
self.keyPressing[3]=false
end
end
function Player:act_rotLeft()
if self.control and self.waiting==-1 and self.cur then
self.ctrlCount=self.ctrlCount+1
self:spin(3)
self.keyPressing[4]=false
end
end
function Player:act_rot180()
if self.control and self.waiting==-1 and self.cur then
self.ctrlCount=self.ctrlCount+2
self:spin(2)
self.keyPressing[5]=false
end
end
function Player:act_hardDrop()
local ENV=self.gameEnv
if self.control and self.waiting==-1 and self.cur then
if self.lastPiece.autoLock and self.frameRun-self.lastPiece.frame<ENV.dropcut then
SFX.play('drop_cancel',.3)
else
if self.curY>self.ghoY then
self:createDropFX()
self.curY=self.ghoY
self.spinLast=false
if self.sound then
SFX.play('drop',nil,self:getCenterX()*.15)
if SETTING.vib>0 then VIB(SETTING.vib+1)end
end
end
if ENV.shakeFX then
self.swingOffset.vy=.6
self.swingOffset.va=self.swingOffset.va+self:getCenterX()*6e-4
end
self.lockDelay=-1
self:drop()
self.keyPressing[6]=false
end
end
end
function Player:act_softDrop()
local ENV=self.gameEnv
self.downing=1
if self.control and self.waiting==-1 and self.cur then
if self.curY>self.ghoY then
self.curY=self.curY-1
self:freshBlock('fresh')
self.spinLast=false
self:checkTouchSound()
elseif ENV.deepDrop then
local CB=self.cur.bk
local y=self.curY-1
while self:ifoverlap(CB,self.curX,y)and y>0 do
y=y-1
end
if y>0 then
self.ghoY=y
self:createDropFX()
self.curY=y
self:freshBlock('move')
SFX.play('swipe')
end
end
end
end
function Player:act_hold()
if self.control then
if self.waiting==-1 then
self:hold()
self.keyPressing[8]=false
end
end
end
function Player:act_func1()
self.gameEnv.fkey1(self)
end
function Player:act_func2()
self.gameEnv.fkey2(self)
end
function Player:act_insLeft(auto)
if not self.cur then
return
end
local x0=self.curX
while not self:ifoverlap(self.cur.bk,self.curX-1,self.curY)do
self:createMoveFX('left')
self.curX=self.curX-1
self:freshBlock('move',true)
end
if self.curX~=x0 then
self.spinLast=false
self:checkTouchSound()
end
if self.gameEnv.shakeFX then
self.swingOffset.vx=-1.5
end
if auto then
if self.ctrlCount==0 then
self.ctrlCount=1
end
else
self.ctrlCount=self.ctrlCount+1
end
end
function Player:act_insRight(auto)
if not self.cur then
return
end
local x0=self.curX
while not self:ifoverlap(self.cur.bk,self.curX+1,self.curY)do
self:createMoveFX('right')
self.curX=self.curX+1
self:freshBlock('move',true)
end
if self.curX~=x0 then
self.spinLast=false
self:checkTouchSound()
end
if self.gameEnv.shakeFX then
self.swingOffset.vx=1.5
end
if auto then
if self.ctrlCount==0 then
self.ctrlCount=1
end
else
self.ctrlCount=self.ctrlCount+1
end
end
function Player:act_insDown()
if self.cur and self.curY>self.ghoY then
local ENV=self.gameEnv
self:createDropFX()
if ENV.shakeFX then
self.swingOffset.vy=.5
end
self.curY=self.ghoY
self.lockDelay=ENV.lock
self.spinLast=false
self:freshBlock('fresh')
self:checkTouchSound()
end
end
function Player:act_down1()
if self.cur and self.curY>self.ghoY then
self:createMoveFX('down')
self.curY=self.curY-1
self:freshBlock('fresh')
self.spinLast=false
end
end
function Player:act_down4()
if self.cur and self.curY>self.ghoY then
local ghoY0=self.ghoY
self.ghoY=max(self.curY-4,self.ghoY)
self:createDropFX()
self.curY,self.ghoY=self.ghoY,ghoY0
self:freshBlock('fresh')
self.spinLast=false
end
end
function Player:act_down10()
if self.cur and self.curY>self.ghoY then
local ghoY0=self.ghoY
self.ghoY=max(self.curY-10,self.ghoY)
self:createDropFX()
self.curY,self.ghoY=self.ghoY,ghoY0
self:freshBlock('fresh')
self.spinLast=false
end
end
function Player:act_dropLeft()
if self.cur then
self:act_insLeft()
self:act_hardDrop()
end
end
function Player:act_dropRight()
if self.cur then
self:act_insRight()
self:act_hardDrop()
end
end
function Player:act_zangiLeft()
if self.cur then
self:act_insLeft()
self:act_insDown()
self:act_insRight()
self:act_hardDrop()
end
end
function Player:act_zangiRight()
if self.cur then
self:act_insRight()
self:act_insDown()
self:act_insLeft()
self:act_hardDrop()
end
end
--------------------------</Action>--------------------------
return Player

View File

@@ -17,6 +17,7 @@ local sList={
wait={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
fall={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
hang={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
hurry={0,1,2,3,4,5,6,7,8,10,1e99},
eventSet=EVENTSETS,
holdMode={'hold','swap'},
}
@@ -212,7 +213,8 @@ scene.widgetList={
WIDGET.newSelector{name='lock', x=730,y=410,w=260,color='O',list=sList.lock,disp=CUSval('lock'),code=CUSsto('lock')},
WIDGET.newSelector{name='wait', x=730,y=520,w=260,color='G',list=sList.wait,disp=CUSval('wait'),code=CUSsto('wait')},
WIDGET.newSelector{name='fall', x=730,y=600,w=260,color='G',list=sList.fall,disp=CUSval('fall'),code=CUSsto('fall')},
WIDGET.newSelector{name='hang', x=730,y=680,w=260,color='G',list=sList.hang,disp=CUSval('hang'),code=CUSsto('hang')},
WIDGET.newSelector{name='hurry', x=730,y=680,w=260,color='G',list=sList.hurry,disp=CUSval('hurry'),code=CUSsto('hurry')},
WIDGET.newSelector{name='hang', x=730,y=760,w=260,color='G',list=sList.hang,disp=CUSval('hang'),code=CUSsto('hang')},
--Copy / Paste / Start
WIDGET.newButton{name='copy', x=1070,y=300,w=310,h=70,color='lR',font=25,code=pressKey"cC"},
@@ -222,19 +224,19 @@ scene.widgetList={
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,font=60,fText=CHAR.icon.back,code=pressKey"escape"},
--Rule set
WIDGET.newSelector{name='eventSet', x=1050,y=740,w=340,color='H',list=sList.eventSet,disp=CUSval('eventSet'),code=CUSsto('eventSet')},
WIDGET.newSelector{name='eventSet', x=1050,y=760,w=340,color='H',list=sList.eventSet,disp=CUSval('eventSet'),code=CUSsto('eventSet')},
--Special rules
WIDGET.newSwitch{name='ospin', x=850, y=820 ,lim=210,disp=CUSval('ospin'), code=CUSrev('ospin')},
WIDGET.newSwitch{name='fineKill', x=850, y=880 ,lim=210,disp=CUSval('fineKill'), code=CUSrev('fineKill')},
WIDGET.newSwitch{name='b2bKill', x=850, y=940 ,lim=210,disp=CUSval('b2bKill'), code=CUSrev('b2bKill')},
WIDGET.newSwitch{name='lockout', x=850, y=1000,lim=210,disp=CUSval('lockout'), code=CUSrev('lockout')},
WIDGET.newSwitch{name='easyFresh', x=1170,y=820 ,lim=250,disp=CUSval('easyFresh'),code=CUSrev('easyFresh')},
WIDGET.newSwitch{name='deepDrop', x=1170,y=880 ,lim=250,disp=CUSval('deepDrop'), code=CUSrev('deepDrop')},
WIDGET.newSwitch{name='bone', x=1170,y=940 ,lim=250,disp=CUSval('bone'), code=CUSrev('bone')},
WIDGET.newSwitch{name='ospin', x=850, y=830, lim=210,disp=CUSval('ospin'), code=CUSrev('ospin')},
WIDGET.newSwitch{name='fineKill', x=850, y=890, lim=210,disp=CUSval('fineKill'), code=CUSrev('fineKill')},
WIDGET.newSwitch{name='b2bKill', x=850, y=950, lim=210,disp=CUSval('b2bKill'), code=CUSrev('b2bKill')},
WIDGET.newSwitch{name='lockout', x=850, y=1010,lim=210,disp=CUSval('lockout'), code=CUSrev('lockout')},
WIDGET.newSwitch{name='easyFresh', x=1170,y=830, lim=250,disp=CUSval('easyFresh'),code=CUSrev('easyFresh')},
WIDGET.newSwitch{name='deepDrop', x=1170,y=890, lim=250,disp=CUSval('deepDrop'), code=CUSrev('deepDrop')},
WIDGET.newSwitch{name='bone', x=1170,y=950, lim=250,disp=CUSval('bone'), code=CUSrev('bone')},
--Next & Hold
WIDGET.newSelector{name='holdMode', x=310, y=890, w=300,color='lY',list=sList.holdMode,disp=CUSval('holdMode'),code=CUSsto('holdMode')},
WIDGET.newSelector{name='holdMode', x=310, y=890, w=300,color='lY',list=sList.holdMode,disp=CUSval('holdMode'),code=CUSsto('holdMode'),hideF=function()return CUSTOMENV.holdCount==0 end},
WIDGET.newSlider{name='nextCount', x=140, y=960, lim=130,w=180,unit=6,disp=CUSval('nextCount'),code=CUSsto('nextCount')},
WIDGET.newSlider{name='holdCount', x=140, y=1030,lim=130,w=180,unit=6,disp=CUSval('holdCount'),code=CUSsto('holdCount')},
WIDGET.newSwitch{name='infHold', x=560, y=960, lim=200, disp=CUSval('infHold'),code=CUSrev('infHold'),hideF=function()return CUSTOMENV.holdCount==0 end},

View File

@@ -12,7 +12,7 @@ local dict--Dict list
local result--Result Lable
local lastTickInput
local waiting--Searching animation timer
local searchWait--Searching animation timer
local selected--Selected option
local scrollPos--Scroll down length
@@ -53,7 +53,7 @@ local function _clearResult()
TABLE.cut(result)
selected=1
scrollPos=0
waiting,lastSearch=0,false
searchWait,lastSearch=0,false
scene.widgetList.copy.hide=false
end
local function _search()
@@ -82,7 +82,7 @@ function scene.sceneInit()
inputBox:clear()
result={}
waiting=0
searchWait=0
selected=1
scrollPos=0
@@ -153,13 +153,13 @@ function scene.update(dt)
if #input==0 then
_clearResult()
else
waiting=.8
searchWait=.8
end
lastTickInput=input
end
if waiting>0 then
waiting=waiting-dt
if waiting<=0 then
if searchWait>0 then
searchWait=searchWait-dt
if searchWait<=0 then
if #input>0 and input~=lastSearch then
_search()
end
@@ -202,7 +202,7 @@ function scene.draw()
gc.rectangle('line',300,180,958,526,5)
gc.rectangle('line',20,180,280,526,5)
if waiting>0 then
if searchWait>0 then
local r=TIME()*2
local R=int(r)%7+1
gc.setColor(1,1,1,1-abs(r%1*2-1))

View File

@@ -11,6 +11,14 @@ local t1,t2,animeType
local studioLogo--Studio logo text object
local logoColor1,logoColor2
local titleTransform={
function(t)gc.translate(0,max(50-t,0)^2/25)end,
function(t)gc.translate(0,-max(50-t,0)^2/25)end,
function(t,i)local d=max(50-t,0)gc.translate(sin(TIME()*3+626*i)*d,cos(TIME()*3+626*i)*d)end,
function(t,i)local d=max(50-t,0)gc.translate(sin(TIME()*3+626*i)*d,-cos(TIME()*3+626*i)*d)end,
function(t)gc.setColor(1,1,1,min(t*.02,1)+rnd()*.2)end,
}
local loadingThread=coroutine.wrap(function()
DAILYLAUNCH=freshDate'q'
if DAILYLAUNCH then
@@ -113,7 +121,7 @@ function scene.sceneInit()
progress=0
maxProgress=10
t1,t2=0,0--Timer
animeType={}for i=1,8 do animeType[i]=rnd(5)end--Random animation type
animeType={}for i=1,#SVG_TITLE_FILL do animeType[i]=rnd(#titleTransform)end--Random animation type
end
function scene.sceneBack()
love.event.quit()
@@ -147,13 +155,6 @@ function scene.update(dt)
end
end
local titleTransform={
function(t)gc.translate(0,max(50-t,0)^2/25)end,
function(t)gc.translate(0,-max(50-t,0)^2/25)end,
function(t,i)local d=max(50-t,0)gc.translate(sin(TIME()*3+626*i)*d,cos(TIME()*3+626*i)*d)end,
function(t,i)local d=max(50-t,0)gc.translate(sin(TIME()*3+626*i)*d,-cos(TIME()*3+626*i)*d)end,
function(t)gc.setColor(1,1,1,min(t*.02,1)+rnd()*.2)end,
}
local titleColor={COLOR.P,COLOR.F,COLOR.V,COLOR.A,COLOR.M,COLOR.N,COLOR.W,COLOR.Y}
function scene.draw()
gc.clear(.08,.08,.084)
@@ -166,7 +167,8 @@ function scene.draw()
end
gc.push('transform')
gc.translate(126,100)
for i=1,8 do
for i=1,#SVG_TITLE_FILL do
local triangles=love.math.triangulate(SVG_TITLE_FILL[i])
local t=t1-i*15
if t>0 then
gc.push('transform')
@@ -176,9 +178,12 @@ function scene.draw()
gc.translate(0,math.abs(10-dt)-10)
end
gc.setColor(titleColor[i][1],titleColor[i][2],titleColor[i][3],min(t*.025,1)*.2)
gc.polygon('fill',SVG_TITLE[i])
for j=1,#triangles do
gc.polygon('fill',triangles[j])
end
gc.setColor(1,1,1,min(t*.025,1))
gc.polygon('line',SVG_TITLE[i])
gc.polygon('line',SVG_TITLE_LINE[i])
if i==8 then gc.polygon('line',SVG_TITLE_LINE[9])end
gc.pop()
end
end

View File

@@ -20,7 +20,10 @@ local sList={
lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,1e99},
wait={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
fall={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
hang={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
hurry={0,1,2,3,4,5,6,7,8,10,1e99},
eventSet=EVENTSETS,
holdMode={'hold','swap'},
}
local scene={}
@@ -87,6 +90,8 @@ scene.widgetList={
WIDGET.newSelector{name='lock', x=730,y=410,w=260,color='O',list=sList.lock,disp=ROOMval('lock'),code=ROOMsto('lock')},
WIDGET.newSelector{name='wait', x=730,y=520,w=260,color='G',list=sList.wait,disp=ROOMval('wait'),code=ROOMsto('wait')},
WIDGET.newSelector{name='fall', x=730,y=600,w=260,color='G',list=sList.fall,disp=ROOMval('fall'),code=ROOMsto('fall')},
WIDGET.newSelector{name='hurry', x=730,y=680,w=260,color='G',list=sList.hurry,disp=ROOMval('hurry'),code=ROOMval('hurry')},
WIDGET.newSelector{name='hang', x=730,y=760,w=260,color='G',list=sList.hang,disp=ROOMval('hang'),code=ROOMval('hang')},
--Capacity & Create & Back
WIDGET.newSelector{name='capacity', x=1070,y=330,w=310,color='lY',list={2,3,4,5,7,10,17,31,49,99},disp=ROOMval('capacity'),code=ROOMsto('capacity')},
@@ -94,18 +99,19 @@ scene.widgetList={
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,font=60,fText=CHAR.icon.back,code=backScene},
--Special rules
WIDGET.newSwitch{name='ospin', x=850, y=760 ,lim=210,disp=ROOMval('ospin'), code=ROOMrev('ospin')},
WIDGET.newSwitch{name='fineKill', x=850, y=850 ,lim=210,disp=ROOMval('fineKill'), code=ROOMrev('fineKill')},
WIDGET.newSwitch{name='b2bKill', x=850, y=940 ,lim=210,disp=ROOMval('b2bKill'), code=ROOMrev('b2bKill')},
WIDGET.newSwitch{name='ospin', x=850, y=850, lim=210,disp=ROOMval('ospin'), code=ROOMrev('ospin')},
WIDGET.newSwitch{name='fineKill', x=850, y=910, lim=210,disp=ROOMval('fineKill'), code=ROOMrev('fineKill')},
WIDGET.newSwitch{name='b2bKill', x=850, y=970, lim=210,disp=ROOMval('b2bKill'), code=ROOMrev('b2bKill')},
WIDGET.newSwitch{name='lockout', x=850, y=1030,lim=210,disp=ROOMval('lockout'), code=ROOMval('lockout')},
WIDGET.newSwitch{name='easyFresh', x=1170,y=760 ,lim=250,disp=ROOMval('easyFresh'),code=ROOMrev('easyFresh')},
WIDGET.newSwitch{name='deepDrop', x=1170,y=850 ,lim=250,disp=ROOMval('deepDrop'), code=ROOMrev('deepDrop')},
WIDGET.newSwitch{name='bone', x=1170,y=940 ,lim=250,disp=ROOMval('bone'), code=ROOMrev('bone')},
WIDGET.newSwitch{name='easyFresh', x=1170,y=850, lim=250,disp=ROOMval('easyFresh'),code=ROOMrev('easyFresh')},
WIDGET.newSwitch{name='deepDrop', x=1170,y=910, lim=250,disp=ROOMval('deepDrop'), code=ROOMrev('deepDrop')},
WIDGET.newSwitch{name='bone', x=1170,y=970, lim=250,disp=ROOMval('bone'), code=ROOMrev('bone')},
--Rule set
WIDGET.newSelector{name='eventSet', x=310,y=880,w=360,color='H',list=sList.eventSet,disp=ROOMval('eventSet'),code=ROOMsto('eventSet')},
WIDGET.newSelector{name='eventSet', x=1050,y=760,w=340,color='H',list=sList.eventSet,disp=ROOMval('eventSet'),code=ROOMval('eventSet')},
--Next & Hold
WIDGET.newSelector{name='holdMode', x=310, y=890, w=300,color='lY',list=sList.holdMode,disp=ROOMval('holdMode'),code=ROOMval('holdMode'),hideF=function()return CUSTOMENV.holdCount==0 end},
WIDGET.newSlider{name='nextCount', x=140, y=960, lim=130,w=200,unit=6,disp=ROOMval('nextCount'),code=ROOMsto('nextCount')},
WIDGET.newSlider{name='holdCount', x=140, y=1030,lim=130,w=200,unit=6,disp=ROOMval('holdCount'),code=ROOMsto('holdCount')},
WIDGET.newSwitch{name='infHold', x=560, y=960, lim=200, disp=ROOMval('infHold'),code=ROOMrev('infHold'),hideF=function()return ROOMENV.holdCount==0 end},

View File

@@ -31,24 +31,24 @@ function scene.draw()
end
scene.widgetList={
WIDGET.newText{name='title', x=640,y=15,font=80},
WIDGET.newText{name='title', x=640,y=15,font=80},
WIDGET.newButton{name='graphic', x=200, y=80, w=240,h=80,color='lC',font=35,code=swapScene('setting_video','swipeR')},
WIDGET.newButton{name='sound', x=1080, y=80, w=240,h=80,color='lC',font=35,code=swapScene('setting_sound','swipeL')},
WIDGET.newButton{name='graphic', x=200, y=80, w=240,h=80,color='lC',font=35,code=swapScene('setting_video','swipeR')},
WIDGET.newButton{name='sound', x=1080, y=80, w=240,h=80,color='lC',font=35,code=swapScene('setting_sound','swipeL')},
WIDGET.newButton{name='layout', x=250, y=540, w=200,h=70,font=35,code=goScene'setting_skin'},
WIDGET.newButton{name='layout', x=250, y=540, w=200,h=70,font=35,code=goScene'setting_skin'},
WIDGET.newButton{name='ctrl', x=290, y=220, w=320,h=80,font=35,code=goScene'setting_control'},
WIDGET.newButton{name='key', x=640, y=220, w=320,h=80,color=MOBILE and'dH',font=35,code=goScene'setting_key'},
WIDGET.newButton{name='touch', x=990, y=220, w=320,h=80,color=not MOBILE and'dH',font=35,code=goScene'setting_touch'},
WIDGET.newSlider{name='reTime', x=330, y=320, w=300,lim=180,unit=10,disp=SETval('reTime'), code=SETsto('reTime'),show=function(S)return(.5+S.disp()*.25).."s"end},
WIDGET.newSelector{name='RS', x=300, y=420, w=300,color='S', disp=SETval('RS'), code=SETsto('RS'),list={'TRS','SRS','SRS_plus','SRS_X','BiRS','ARS_Z','ASC','ASC_plus','C2','C2_sym','Classic','Classic_plus','None','None_plus'}},
WIDGET.newSelector{name='menuPos', x=980, y=320, w=300,color='O', disp=SETval('menuPos'), code=SETsto('menuPos'),list={'left','middle','right'}},
WIDGET.newSwitch{name='sysCursor' ,x=1060, y=390, lim=580, disp=SETval('sysCursor'),code=function()SETTING.sysCursor=not SETTING.sysCursor applyCursor()end},
WIDGET.newSwitch{name='autoPause', x=1060, y=450, lim=580, disp=SETval('autoPause'),code=SETrev('autoPause')},
WIDGET.newSwitch{name='autoSave', x=1060, y=500, lim=580, disp=SETval('autoSave'), code=SETrev('autoSave')},
WIDGET.newSwitch{name='autoLogin', x=960, y=580, lim=480, disp=SETval('autoLogin'),code=SETrev('autoLogin')},
WIDGET.newSwitch{name='simpMode', x=960, y=640, lim=480, disp=SETval('simpMode'),
WIDGET.newButton{name='ctrl', x=290, y=220, w=320,h=80,font=35,code=goScene'setting_control'},
WIDGET.newButton{name='key', x=640, y=220, w=320,h=80,color=MOBILE and'dH',font=35,code=goScene'setting_key'},
WIDGET.newButton{name='touch', x=990, y=220, w=320,h=80,color=not MOBILE and'dH',font=35,code=goScene'setting_touch'},
WIDGET.newSlider{name='reTime', x=330, y=320, w=300,lim=180,unit=10,disp=SETval('reTime'), code=SETsto('reTime'),show=function(S)return(.5+S.disp()*.25).."s"end},
WIDGET.newSelector{name='RS', x=300, y=420, w=300,color='S', disp=SETval('RS'), code=SETsto('RS'),list={'TRS','SRS','SRS_plus','SRS_X','BiRS','ARS_Z','ASC','ASC_plus','C2','C2_sym','Classic','Classic_plus','None','None_plus'}},
WIDGET.newSelector{name='menuPos',x=980, y=320, w=300,color='O', disp=SETval('menuPos'), code=SETsto('menuPos'),list={'left','middle','right'}},
WIDGET.newSwitch{name='sysCursor',x=1060, y=390, lim=580, disp=SETval('sysCursor'),code=function()SETTING.sysCursor=not SETTING.sysCursor applyCursor()end},
WIDGET.newSwitch{name='autoPause',x=1060, y=450, lim=580, disp=SETval('autoPause'),code=SETrev('autoPause')},
WIDGET.newSwitch{name='autoSave', x=1060, y=500, lim=580, disp=SETval('autoSave'), code=SETrev('autoSave')},
WIDGET.newSwitch{name='autoLogin',x=960, y=580, lim=480, disp=SETval('autoLogin'),code=SETrev('autoLogin')},
WIDGET.newSwitch{name='simpMode', x=960, y=640, lim=480, disp=SETval('simpMode'),
code=function()
SETTING.simpMode=not SETTING.simpMode
for i=1,#SCN.stack,2 do
@@ -58,7 +58,7 @@ scene.widgetList={
end
end
end},
WIDGET.newButton{name='back', x=1140, y=640, w=170,h=80,font=60,fText=CHAR.icon.back,code=backScene},
WIDGET.newButton{name='back', x=1140, y=640, w=170,h=80,font=60,fText=CHAR.icon.back,code=backScene},
}
return scene

View File

@@ -69,16 +69,16 @@ end
gc.setDefaultFilter('linear','linear')
TEXTURE.title=NSC(1160,236)--Title image (Middle: 580,118)
TEXTURE.title=NSC(1130,236)--Title image (Middle: 580,118)
do
for i=1,8 do
local triangles=love.math.triangulate(SVG_TITLE[i])
gc.setLineWidth(12)
for i=1,#SVG_TITLE_FILL do
local triangles=love.math.triangulate(SVG_TITLE_FILL[i])
gc.translate(12*i,i==1 and 8 or 14)
gc.setLineWidth(16)
gc.setColor(COLOR.Z)
gc.polygon('line',SVG_TITLE[i])
gc.polygon('line',SVG_TITLE_FILL[i])
gc.setColor(.2,.2,.2)
for j=1,#triangles do
@@ -89,18 +89,18 @@ do
end
end
TEXTURE.title_color=NSC(1160,236)--Title image (colored)
TEXTURE.title_color=NSC(1130,236)--Title image (colored)
do
local titleColor={COLOR.P,COLOR.F,COLOR.V,COLOR.A,COLOR.M,COLOR.N,COLOR.W,COLOR.Y}
for i=1,8 do
local triangles=love.math.triangulate(SVG_TITLE[i])
local triangles=love.math.triangulate(SVG_TITLE_FILL[i])
gc.translate(12*i,i==1 and 8 or 14)
gc.setLineWidth(16)
gc.setLineWidth(12)
gc.setColor(COLOR.Z)
gc.polygon('line',SVG_TITLE[i])
gc.polygon('line',SVG_TITLE_FILL[i])
gc.setLineWidth(4)
gc.setColor(COLOR.D)
@@ -109,11 +109,9 @@ do
end
gc.setColor(.2+.8*titleColor[i][1],.2+.8*titleColor[i][2],.2+.8*titleColor[i][3],.3)
gc.translate(-4,-4)
for j=1,#triangles do
gc.polygon('fill',triangles[j])
end
gc.translate(4,4)
gc.translate(-12*i,i==1 and -8 or -14)
end

View File

@@ -15,18 +15,21 @@ return[=[
新增:
新模式:大爆炸
新模式:策略堆叠(原设计来自游戏Cambridge, by NOT_A_ROBOT)
添加lockout判负规则(默认关闭)
新机制:出块延迟打断(ARE打断)(默认不开启此功能) #471
添加锁定延迟判负(lockout)规则(默认关闭)
全局默认使用5帧窒息延迟
尝试支持摇杆和扳机
改动:
出块/消行延迟真的是0延迟,不再有一帧等待了
TRS的S/Z添加四个踢墙防止在一些地方卡死
生成位置预览开启后hold的生成位置也可见 #453
优化pc训练模式体验,添加胜利条件,不再无尽
堆积模式添加15帧的窒息延迟 #465
小程序arm加入计时器和重置按钮
代码:
bgm模块可限制最大加载数不容易达到上限导致没声 #447
bgm模块可限制最大加载数,不容易达到上限导致没声 #447
语音模块支持设置轻微随机音调偏移半径(游戏内固定使用1)
较大规模整理玩家相关代码,重构出块延迟和消行延迟逻辑
修复:
机翻语言超级消除无行数显示 #462
竞速-效率左侧信息颜色问题

View File

@@ -1,5 +1,5 @@
return{
["apkCode"]=406,
["apkCode"]=407,
["code"]=1700,
["string"]="V0.17.0",
["room"]="ver A-2",