Compare commits

..

62 Commits

Author SHA1 Message Date
MrZ626
fa0dc1f946 更新版本号,修改更新历史 2021-05-20 22:45:01 +08:00
MrZ626
8f860b21a8 优化开局倒计时画面效果 2021-05-20 22:12:10 +08:00
MrZ626
2a5105a49e 整理老旧自定义-消除模式代码,修复左侧消息显示问题 2021-05-20 22:09:24 +08:00
MrZ626
0fa9f85a8d 优化spike指示器绘制代码 2021-05-20 20:56:59 +08:00
MrZ626
202117a60e 垃圾行缓冲警告添加震动效果 2021-05-20 20:12:22 +08:00
MrZ626
35c7935f9c spike指示器显示优化 2021-05-20 15:48:28 +08:00
MrZ626
d953d623a2 微调联网房间内准备前ui,修改键盘准备/观战快捷键 2021-05-20 14:35:55 +08:00
MrZ626
4ddccd7211 混战模式和联网对战允许开局跳块 2021-05-20 14:21:11 +08:00
MrZ626
4a2d13c6d7 允许开局跳过若干next时,倒计时数字颜色和动画样式略有不同 2021-05-20 14:21:09 +08:00
MrZ626
c92b4c1863 修复手机端词典里的官网链接点不开 2021-05-20 13:34:15 +08:00
MrZ626
fb736c5a7a 调整模块加载顺序,修复一处cc库相关的报错 2021-05-20 13:29:18 +08:00
MrZ626
9046a0a7c8 整理版本更新代码,临时改成每次启动刷新所有lib文件 2021-05-20 12:27:08 +08:00
MrZ626
4173441d3c 修改更新历史 2021-05-20 00:24:48 +08:00
MrZ626
b5c3af05d8 整理代码 2021-05-20 00:04:12 +08:00
MrZ626
6fa9aa30fa 新增虚拟按键样式设置 2021-05-20 00:02:37 +08:00
MrZ626
41ce44fc0e 修复手机端文本框响应逻辑错误 2021-05-19 21:32:47 +08:00
MrZ626
59848cd559 尝试修复手机端文本框响应逻辑错误 2021-05-19 18:12:09 +08:00
MrZ626
092c944d27 整理代码 2021-05-19 18:12:09 +08:00
MrZ626
8ec051f523 添加一些tip 2021-05-19 16:15:56 +08:00
MrZ626
22cc708a65 赞助名单添加一位 2021-05-19 16:15:56 +08:00
MrZ626
4e577a01ae 删除一处测试代码,更新版本号,修改更新历史 2021-05-19 02:12:24 +08:00
MrZ626
5b43ff8c45 联网推进(观战功能测试) 2021-05-19 02:08:29 +08:00
MrZ626
d07075ca9c 联网推进(微调房间内交互,观战模式不再尝试发送录像流) 2021-05-18 17:39:00 +08:00
MrZ626
cd49507a2b 联网推进(增加观战相关代码) 2021-05-18 17:16:58 +08:00
MrZ626
00464f1e80 整理代码 2021-05-18 15:44:01 +08:00
MrZ626
6ec902e618 适当上移next和hold栏 2021-05-18 11:52:06 +08:00
MrZ626
30e276b132 新的对战房间数据结构,整理相关内容 2021-05-18 03:13:53 +08:00
MrZ626
b8597d1518 适配新版玩家连接状态修改方式 2021-05-18 01:45:28 +08:00
MrZ626
5543f29e4f 跟进更新历史 2021-05-18 01:12:40 +08:00
MrZ626
dc67239382 词典添加spike词条 2021-05-18 01:12:25 +08:00
MrZ626
2a571bbb97 网战录像流强行将每段数据长度补足到3的倍数保证base64后的数据不会被等号填充 2021-05-18 01:04:13 +08:00
MrZ626
2824bef04a 网战不再生成没连接成功的玩家对象 2021-05-18 00:59:41 +08:00
MrZ626
8fc7ebdab7 移除next和hold栏上的文本 2021-05-17 22:32:59 +08:00
MrZ626
793d6780f3 更新虚拟按键样式,略微优化性能 2021-05-17 22:32:59 +08:00
MrZ626
605561148b 修复未登录时游戏启动就进登录菜单 2021-05-17 22:29:56 +08:00
MrZ626
54daef0cd9 修复控件系统inputBox焦点问题 2021-05-17 22:29:56 +08:00
MrZ626
ac0ff16537 版本信息添加short字段,上报房间版本格式从code改为short,微调房间列表界面ui 2021-05-17 22:29:56 +08:00
MrZ626
e44053446a 更新ws连接服务器用的域名 2021-05-17 22:29:56 +08:00
MrZ626
d4fb606c72 再更新新房间列表ui 2021-05-17 15:15:12 +08:00
MrZ626
4cfdd4e58b 修复ws状态指示器在屏幕尺寸不标准时显示位置错误 2021-05-17 14:57:53 +08:00
MrZ626
3b82a144ea 升级本地和服务器提供的房间数据格式(警告:和旧版本不兼容),修复“游戏中”标记会被带到别的房间 2021-05-17 01:02:04 +08:00
MrZ626
2f06c1b476 前推版本适配代码,更新版本号 2021-05-16 21:35:22 +08:00
MrZ626
25b6b2c5ba 修改更新日志 2021-05-16 21:29:35 +08:00
MrZ626
9948505145 微调spike的画面效果 2021-05-16 21:26:23 +08:00
MrZ626
9d8feab2cc 添加spike计数器开关,调整画面设置界面布局 2021-05-16 20:56:13 +08:00
MrZ626
bcb5d3eba4 新增spike计数器 2021-05-16 20:29:01 +08:00
MrZ626
d7a10c00ed 再优化一点玩家绘制性能,整理代码 2021-05-16 19:10:03 +08:00
MrZ626
d2593cfb81 整理初始化空玩家代码 2021-05-16 16:32:08 +08:00
MrZ626
8101cf89f8 修复命令行空白输入报错
closes #63
2021-05-16 14:15:14 +08:00
MrZ626
8636c6dcd5 重新启用margin time,但基于帧而不是时间 2021-05-16 14:09:06 +08:00
MrZ626
b9c5599f95 修复对战房间内按钮会触发聊天框 2021-05-16 03:16:07 +08:00
MrZ626
93f854e6e4 简化/混淆水印代码 2021-05-16 03:07:25 +08:00
MrZ626
ffc09b0801 房间内文本框操作更自然 2021-05-16 02:55:25 +08:00
MrZ626
d246064ded 新增几个灰色tip 2021-05-16 01:59:35 +08:00
MrZ626
468f264545 整理代码,修改更新日志 2021-05-15 23:50:44 +08:00
MrZ626
9bec223b09 升级控件模块,封装focus相关的几个静态方法 2021-05-15 23:32:14 +08:00
MrZ626
4606bb4d01 调整进入联网游戏菜单的音效播放时机 2021-05-15 23:31:44 +08:00
MrZ626
c8405c8924 词典添加游戏官网 2021-05-15 20:58:09 +08:00
MrZ626
95a33c0e6c 主菜单按钮行为更容易理解,添加连接音效和连接成功音效 2021-05-15 20:17:31 +08:00
MrZ626
ed2ad35dde 修改默认空用户名,修复结算时显示胜利者可能报错 2021-05-15 17:57:30 +08:00
MrZ626
234ae08c76 微调双语tips 2021-05-15 17:57:16 +08:00
MrZ626
d21506b8d7 微调房间内玩家对象的绘制 2021-05-15 17:57:09 +08:00
52 changed files with 822 additions and 549 deletions

View File

@@ -160,6 +160,7 @@ function love.touchpressed(id,x,y)
if SCN.swapping then return end if SCN.swapping then return end
if not touching then if not touching then
touching=id touching=id
WIDGET.unFocus(true)
love.touchmoved(id,x,y,0,0) love.touchmoved(id,x,y,0,0)
end end
x,y=xOy:inverseTransformPoint(x,y) x,y=xOy:inverseTransformPoint(x,y)
@@ -172,14 +173,10 @@ function love.touchmoved(_,x,y,dx,dy)
x,y=xOy:inverseTransformPoint(x,y) x,y=xOy:inverseTransformPoint(x,y)
if SCN.touchMove then SCN.touchMove(x,y,dx/SCR.k,dy/SCR.k)end if SCN.touchMove then SCN.touchMove(x,y,dx/SCR.k,dy/SCR.k)end
if WIDGET.sel then if WIDGET.sel then
if touching then if touching then WIDGET.drag(x,y,dx,dy)end
WIDGET.drag(x,y,dx,dy)
end
else else
WIDGET.cursorMove(x,y) WIDGET.cursorMove(x,y)
if not WIDGET.sel then if not WIDGET.sel then touching=false end
touching=false
end
end end
end end
function love.touchreleased(id,x,y) function love.touchreleased(id,x,y)
@@ -188,10 +185,9 @@ function love.touchreleased(id,x,y)
if id==touching then if id==touching then
WIDGET.press(x,y,1) WIDGET.press(x,y,1)
WIDGET.release(x,y) WIDGET.release(x,y)
WIDGET.cursorMove(x,y)
WIDGET.unFocus()
touching=false touching=false
if WIDGET.sel and not WIDGET.sel.keepFocus then
WIDGET.sel=false
end
end end
if SCN.touchUp then SCN.touchUp(x,y)end if SCN.touchUp then SCN.touchUp(x,y)end
if(x-lastX)^2+(y-lastY)^2<62 then if(x-lastX)^2+(y-lastY)^2<62 then
@@ -214,7 +210,7 @@ local function noDevkeyPressed(key)
end end
end end
elseif key=="f4"then if not kb.isDown("lalt","ralt")then LOG.copy()end elseif key=="f4"then if not kb.isDown("lalt","ralt")then LOG.copy()end
elseif key=="f5"then if WIDGET.sel then print(WIDGET.sel)end elseif key=="f5"then print(WIDGET.isFocus()or"no widget selected")
elseif key=="f6"then for k,v in next,_G do print(k,v)end elseif key=="f6"then for k,v in next,_G do print(k,v)end
elseif key=="f7"then if love._openConsole then love._openConsole()end elseif key=="f7"then if love._openConsole then love._openConsole()end
elseif key=="f8"then devMode=nil LOG.print("DEBUG OFF") elseif key=="f8"then devMode=nil LOG.print("DEBUG OFF")
@@ -224,8 +220,8 @@ local function noDevkeyPressed(key)
elseif key=="f12"then devMode=4 LOG.print("DEBUG 4") elseif key=="f12"then devMode=4 LOG.print("DEBUG 4")
elseif key=="\\"then _G["\100\114\97\119\70\87\77"]=NULL elseif key=="\\"then _G["\100\114\97\119\70\87\77"]=NULL
elseif devMode==2 then elseif devMode==2 then
if WIDGET.sel then local W=WIDGET.sel
local W=WIDGET.sel if W then
if key=="left"then W.x=W.x-10 if key=="left"then W.x=W.x-10
elseif key=="right"then W.x=W.x+10 elseif key=="right"then W.x=W.x+10
elseif key=="up"then W.y=W.y-10 elseif key=="up"then W.y=W.y-10
@@ -464,11 +460,11 @@ local devColor={
local WS=WS local WS=WS
local WSnames={'app','user','play','stream','chat'} local WSnames={'app','user','play','stream','chat'}
local WScolor={ local WScolor={
{1,.5,.5,.7}, {1,.6,.6,.7},
{1,.8,.3,.7}, {1,.8,.4,.7},
{1,1,.4,.7}, {1,1,.5,.7},
{.4,1,.7,.7}, {.5,1,.8,.7},
{.5,.8,1,.7}, {.6,.9,1,.7},
} }
local ws_deadImg=DOGC{20,20, local ws_deadImg=DOGC{20,20,
{'setFT',20}, {'setFT',20},
@@ -626,26 +622,26 @@ function love.run()
--Websocket status --Websocket status
gc_push('transform') gc_push('transform')
gc.translate(SCR.w,SCR.h-100) gc.translate(SCR.w,SCR.h)
gc.scale(SCR.k) gc.scale(SCR.k)
for i=1,5 do for i=1,5 do
local status=WS.status(WSnames[i]) local status=WS.status(WSnames[i])
gc_setColor(WScolor[i]) gc_setColor(WScolor[i])
gc_rectangle('fill',0,20*i,-80,-20) gc_rectangle('fill',0,20*i-100,-80,-20)
if status=='dead'then if status=='dead'then
gc_setColor(1,1,1) gc_setColor(1,1,1)
gc_draw(ws_deadImg,-20,20*i-20) gc_draw(ws_deadImg,-20,20*i-120)
elseif status=='connecting'then elseif status=='connecting'then
gc_setColor(1,1,1,.5+.3*sin(time*6.26)) gc_setColor(1,1,1,.5+.3*sin(time*6.26))
gc_draw(ws_connectingImg,-20,20*i-20) gc_draw(ws_connectingImg,-20,20*i-120)
elseif status=='running'then elseif status=='running'then
gc_setColor(1,1,1) gc_setColor(1,1,1)
gc_draw(ws_runningImg,-20,20*i-20) gc_draw(ws_runningImg,-20,20*i-120)
end end
local t1,t2,t3=WS.getTimers(WSnames[i]) local t1,t2,t3=WS.getTimers(WSnames[i])
gc_setColor(1,1,1,t1)gc_rectangle('fill',-60,20*i,-20,-20) gc_setColor(1,1,1,t1)gc_rectangle('fill',-60,20*i-100,-20,-20)
gc_setColor(0,1,0,t2)gc_rectangle('fill',-40,20*i,-20,-20) gc_setColor(0,1,0,t2)gc_rectangle('fill',-40,20*i-100,-20,-20)
gc_setColor(1,0,0,t3)gc_rectangle('fill',-20,20*i,-20,-20) gc_setColor(1,0,0,t3)gc_rectangle('fill',-20,20*i-100,-20,-20)
end end
gc_pop() gc_pop()

View File

@@ -10,33 +10,28 @@ return function(name,libName)
local fs=love.filesystem local fs=love.filesystem
local platform={'arm64-v8a','armeabi-v7a'} local platform={'arm64-v8a','armeabi-v7a'}
local libFunc=package.loadlib(SAVEDIR.."/lib/"..libName.Android,libName.libFunc) for i=1,#platform do
if libFunc then local soFile,_,_,mes1=fs.read('data',"libAndroid/"..platform[i].."/"..libName.Android)
LOG.print(name.." lib loaded",'message') if soFile then
else local success,mes2=fs.write("lib/"..libName.Android,soFile)
for i=1,#platform do if success then
local soFile,_,_,mes1=fs.read('data',"libAndroid/"..platform[i].."/"..libName.Android) libFunc,mes2=package.loadlib(SAVEDIR.."/lib/"..libName.Android,libName.libFunc)
if soFile then if libFunc then
local success,mes2=fs.write("lib/"..libName.Android,soFile) LOG.print(name.." lib loaded",'message')
if success then break
libFunc,mes2=package.loadlib(SAVEDIR.."/lib/"..libName.Android,libName.libFunc)
if libFunc then
LOG.print(name.." lib loaded",'message')
break
else
LOG.print("Cannot load "..name..": "..mes2,'error')
end
else else
LOG.print(("Write %s-%s to saving failed: %s"):format(name,platform[i],mes2),'error') LOG.print("Cannot load "..name..": "..mes2,'error')
end end
else else
LOG.print(("Read %s-%s to saving failed: %s"):format(name,platform[i],mes1),'error') LOG.print(("Write %s-%s to saving failed: %s"):format(name,platform[i],mes2),'error')
end end
else
LOG.print(("Read %s-%s to saving failed: %s"):format(name,platform[i],mes1),'error')
end end
if not libFunc then end
LOG.print("Cannot load "..name,'error') if not libFunc then
return LOG.print("Cannot load "..name,'error')
end return
end end
return libFunc() return libFunc()
else else

View File

@@ -1,8 +1,7 @@
-- local host="127.0.0.1" -- local host="127.0.0.1"
-- local host="192.168.114.102" -- local host="192.168.114.102"
-- local host="krakens.tpddns.cn" local host="krakens.tpddns.cn"
-- local host="hdustea.3322.org" -- local host="game.techmino.org"
local host="game.techmino.org"
local port="10026" local port="10026"
local path="/tech/socket/v1" local path="/tech/socket/v1"

View File

@@ -1,12 +1,11 @@
local kb=love.keyboard local kb,gc=love.keyboard,love.graphics
local gc=love.graphics
local next=next
local int,abs=math.floor,math.abs local int,abs=math.floor,math.abs
local max,min=math.max,math.min local max,min=math.max,math.min
local sub=string.sub local sub,ins=string.sub,table.insert
local ins=table.insert local getFont,setFont,mStr=getFont,setFont,mStr
local setFont,mStr=setFont,mStr local mDraw,mDraw_X,mDraw_Y=ADRAW.draw,ADRAW.simpX,ADRAW.simpY
local mDraw_X,mDraw_Y=ADRAW.simpX,ADRAW.simpY
local clearIcon=DOGC{40,40, local clearIcon=DOGC{40,40,
{'setLW',6}, {'setLW',6},
@@ -519,7 +518,7 @@ function slider:drag(x)
if p~=P then if p~=P then
self.code(P) self.code(P)
end end
if self.change and TIME()-self.lastTime>.18 then if self.change and TIME()-self.lastTime>.26 then
self.lastTime=TIME() self.lastTime=TIME()
self.change() self.change()
end end
@@ -1035,7 +1034,7 @@ WIDGET.indexMeta={
end end
} }
function WIDGET.set(list) function WIDGET.set(list)
WIDGET.sel=false WIDGET.unFocus()
WIDGET.active=list or NONE WIDGET.active=list or NONE
--Reset all widgets --Reset all widgets
@@ -1072,23 +1071,42 @@ function WIDGET.setLang(widgetText)
end end
end end
end end
function WIDGET.isFocus(W)
return W==nil and WIDGET.sel or WIDGET.sel==W
end
function WIDGET.focus(W)
if WIDGET.sel==W then return end
if WIDGET.sel and WIDGET.sel.type=='inputBox'then kb.setTextInput(false)end
WIDGET.sel=W
if W and W.type=='inputBox'then
local _,y1=SCR.xOy:transformPoint(0,W.y+W.h)
kb.setTextInput(true,0,y1,1,1)
end
end
function WIDGET.unFocus(force)
local W=WIDGET.sel
if W and(force or not W.keepFocus)then
if W.type=='inputBox'then kb.setTextInput(false)end
WIDGET.sel=false
end
end
function WIDGET.cursorMove(x,y) function WIDGET.cursorMove(x,y)
for _,W in next,WIDGET.active do for _,W in next,WIDGET.active do
if not W.hide and W.resCtr and W:isAbove(x,y)then if not W.hide and W.resCtr and W:isAbove(x,y)then
WIDGET.sel=W WIDGET.focus(W)
return return
end end
end end
if WIDGET.sel and not WIDGET.sel.keepFocus then if WIDGET.sel and not WIDGET.sel.keepFocus then
WIDGET.sel=false WIDGET.unFocus()
end end
end end
function WIDGET.press(x,y,k) function WIDGET.press(x,y,k)
local W=WIDGET.sel local W=WIDGET.sel
if not W then return end if not W then return end
W:press(x,y,k) W:press(x,y,k)
if W.hide then WIDGET.sel=false end if W.hide then WIDGET.unFocus()end
end end
function WIDGET.drag(x,y,dx,dy) function WIDGET.drag(x,y,dx,dy)
local W=WIDGET.sel local W=WIDGET.sel
@@ -1096,7 +1114,7 @@ function WIDGET.drag(x,y,dx,dy)
if W.type=='slider'or W.type=='textBox'then if W.type=='slider'or W.type=='textBox'then
W:drag(x,y,dx,dy) W:drag(x,y,dx,dy)
elseif not W:isAbove(x,y)then elseif not W:isAbove(x,y)then
WIDGET.sel=false WIDGET.unFocus(true)
end end
end end
function WIDGET.release(x,y) function WIDGET.release(x,y)
@@ -1107,25 +1125,24 @@ function WIDGET.release(x,y)
end end
end end
function WIDGET.keyPressed(k) function WIDGET.keyPressed(k)
local W=WIDGET.sel
if k=="space"or k=="return"then if k=="space"or k=="return"then
WIDGET.press() WIDGET.press()
elseif kb.isDown("lshift","lalt","lctrl")and(k=="left"or k=="right")then elseif kb.isDown("lshift","lalt","lctrl")and(k=="left"or k=="right")then
--When hold [↑], control slider with left/right --When hold [↑], control slider with left/right
local W=WIDGET.sel
if W and W.type=='slider'or W.type=='selector'then if W and W.type=='slider'or W.type=='selector'then
W:arrowKey(k=="left") W:arrowKey(k=="left")
end end
elseif k=="up"or k=="down"or k=="left"or k=="right"then elseif k=="up"or k=="down"or k=="left"or k=="right"then
if not WIDGET.sel then if not W then
for _,W in next,WIDGET.active do for _,w in next,WIDGET.active do
if not W.hide and W.isAbove then if not w.hide and w.isAbove then
WIDGET.sel=W WIDGET.focus(w)
return return
end end
end end
return return
end end
local W=WIDGET.sel
if not W.getCenter then return end if not W.getCenter then return end
local WX,WY=W:getCenter() local WX,WY=W:getCenter()
local dir=(k=="right"or k=="down")and 1 or -1 local dir=(k=="right"or k=="down")and 1 or -1
@@ -1151,10 +1168,9 @@ function WIDGET.keyPressed(k)
end end
end end
if tar then if tar then
WIDGET.sel=tar WIDGET.focus(tar)
end end
else else
local W=WIDGET.sel
if W and W.type=='inputBox'then if W and W.type=='inputBox'then
W:keypress(k) W:keypress(k)
end end
@@ -1205,12 +1221,7 @@ end
function WIDGET.update() function WIDGET.update()
for _,W in next,WIDGET.active do for _,W in next,WIDGET.active do
if W.hideF then if W.hideF then W.hide=W.hideF()end
local h=W.hideF()
if h~=W.hide then
W.hide=h
end
end
if W.update then W:update()end if W.update then W:update()end
end end
end end

View File

@@ -1,7 +1,8 @@
VERSION={ VERSION={
code=1408, code=1501,
string="Alpha V0.14.8", short="V0.15.1",
name="冰激凌 Icecream", string="Alpha V0.15.1",
name="耀斑 Flare",
} }
function love.conf(t) function love.conf(t)
t.identity='Techmino'--Saving folder t.identity='Techmino'--Saving folder

View File

@@ -82,10 +82,10 @@ SKIN= require"parts.skin"
USERS= require"parts.users" USERS= require"parts.users"
NET= require"parts.net" NET= require"parts.net"
VK= require"parts.virtualKey" VK= require"parts.virtualKey"
PLY= require"parts.player"
netPLY= require"parts.netPlayer"
AIFUNC= require"parts.ai" AIFUNC= require"parts.ai"
AIBUILDER= require"parts.AITemplate" AIBUILDER= require"parts.AITemplate"
PLY= require"parts.player"
netPLY= require"parts.netPlayer"
MODES= require"parts.modes" MODES= require"parts.modes"
--Initialize field[1] --Initialize field[1]
@@ -236,18 +236,16 @@ for _,v in next,fs.getDirectoryItems("parts/scenes")do
LANG.addScene(sceneName) LANG.addScene(sceneName)
end end
end end
LANG.set(SETTING.lang)
--Update data --Update data
do do
local needSave local needSave,autoRestart
local autoRestart
if type(STAT.version)~='number'then if type(STAT.version)~='number'then
STAT.version=0 STAT.version=0
needSave=true needSave=true
end end
if STAT.version<1300 then if STAT.version<1302 then
STAT.frame=math.floor(STAT.time*60) STAT.frame=math.floor(STAT.time*60)
STAT.lastPlay='sprint_10l' STAT.lastPlay='sprint_10l'
RANKS.sprintFix=nil RANKS.sprintFix=nil
@@ -256,38 +254,30 @@ do
for _,name in next,fs.getDirectoryItems("replay")do for _,name in next,fs.getDirectoryItems("replay")do
fs.remove("replay/"..name) fs.remove("replay/"..name)
end end
end
if STAT.version<1302 then
if RANKS.pctrain_n then RANKS.pctrain_n=0 end if RANKS.pctrain_n then RANKS.pctrain_n=0 end
if RANKS.pctrain_l then RANKS.pctrain_l=0 end if RANKS.pctrain_l then RANKS.pctrain_l=0 end
fs.remove("conf/settings") fs.remove("conf/settings")
needSave=true needSave=true
autoRestart=true autoRestart=true
end end
if STAT.version<1400 then if STAT.version<1405 then
fs.remove("conf/user") fs.remove("conf/user")
fs.remove("conf/key") fs.remove("conf/key")
needSave=true needSave=true
autoRestart=true autoRestart=true
end end
if STAT.version<1405 then
fs.remove("conf/user")
autoRestart=true
end
if not TABLE.find({8,10,13,17,22,29,37,47,62,80,100},SETTING.frameMul)then
SETTING.frameMul=100
end
SETTING.appLock=nil
for _,v in next,VK_org do v.color=nil end
if STAT.version~=VERSION.code then if STAT.version~=VERSION.code then
STAT.version=VERSION.code STAT.version=VERSION.code
CLEAR("lib")
needSave=true needSave=true
autoRestart=true autoRestart=true
end end
if not SETTING.VKSkin then SETTING.VKSkin=1 end
if not TABLE.find({8,10,13,17,22,29,37,47,62,80,100},SETTING.frameMul)then
SETTING.frameMul=100
end
SETTING.appLock=nil
for _,v in next,VK_org do v.color=nil end
if RANKS.GM then RANKS.GM=0 end if RANKS.GM then RANKS.GM=0 end
if RANKS.infinite then RANKS.infinite=6 end if RANKS.infinite then RANKS.infinite=6 end
if RANKS.infinite_dig then RANKS.infinite_dig=6 end if RANKS.infinite_dig then RANKS.infinite_dig=6 end
@@ -326,4 +316,7 @@ do
if autoRestart then if autoRestart then
love.event.quit('restart') love.event.quit('restart')
end end
end end
LANG.set(SETTING.lang)
VK.setShape(SETTING.VKSkin)

BIN
media/SFX/connect.ogg Normal file

Binary file not shown.

BIN
media/SFX/connected.ogg Normal file

Binary file not shown.

View File

@@ -1,4 +1,3 @@
local kb=love.keyboard
local gc=love.graphics local gc=love.graphics
local gc_push,gc_pop=gc.push,gc.pop local gc_push,gc_pop=gc.push,gc.pop
local gc_origin,gc_translate=gc.origin,gc.translate local gc_origin,gc_translate=gc.origin,gc.translate
@@ -11,8 +10,8 @@ local ins,rem=table.insert,table.remove
local SETTING,GAME,SCR=SETTING,GAME,SCR local SETTING,GAME,SCR=SETTING,GAME,SCR
--System --System
function enableTextInput()if not MOBILE then kb.setTextInput(true)end end
function switchFullscreen() function switchFullscreen()
SETTING.fullscreen=not SETTING.fullscreen SETTING.fullscreen=not SETTING.fullscreen
love.window.setFullscreen(SETTING.fullscreen) love.window.setFullscreen(SETTING.fullscreen)
@@ -545,36 +544,6 @@ end
--Game draw --Game draw
do--function drawFWM()
local m={
string.char(230,184,184,230,136,143,228,189,156,232,128,133,58,77,114,90,95,50,54,10,228,187,187,228,189,149,232,167,134,233,162,145,47,231,155,180,230,146,173,228,184,141,229,190,151,229,135,186,231,142,176,230,173,164,230,176,180,229,141,176,10,228,187,187,228,189,149,232,189,172,232,191,176,229,163,176,230,152,142,230,151,160,230,149,136),
string.char(230,184,184,230,136,143,228,189,156,232,128,133,58,77,114,90,95,50,54,10,228,187,187,228,189,149,232,167,134,233,162,145,47,231,155,180,230,146,173,228,184,141,229,190,151,229,135,186,231,142,176,230,173,164,230,176,180,229,141,176,10,228,187,187,228,189,149,232,189,172,232,191,176,229,163,176,230,152,142,230,151,160,230,149,136),
string.char(230,184,184,230,136,143,228,189,156,232,128,133,58,77,114,90,95,50,54,10,228,187,187,228,189,149,232,167,134,233,162,145,47,231,155,180,230,146,173,228,184,141,229,190,151,229,135,186,231,142,176,230,173,164,230,176,180,229,141,176,10,228,187,187,228,189,149,232,189,172,232,191,176,229,163,176,230,152,142,230,151,160,230,149,136),
string.char(65,117,116,104,111,114,58,32,77,114,90,95,50,54,10,82,101,99,111,114,100,105,110,103,115,32,99,111,110,116,97,105,110,105,110,103,32,116,104,105,115,10,119,97,116,101,114,109,97,114,107,32,97,114,101,32,117,110,97,117,116,104,111,114,105,122,101,100),
string.char(67,114,195,169,97,116,101,117,114,32,100,117,32,106,101,117,58,32,77,114,90,95,50,54,10,69,110,114,101,103,105,115,116,114,101,109,101,110,116,32,110,111,110,32,97,117,116,111,114,105,115,195,169,10,99,111,110,116,101,110,97,110,116,32,99,101,32,102,105,108,105,103,114,97,110,101),
string.char(65,117,116,111,114,58,32,77,114,90,95,50,54,10,71,114,97,98,97,99,105,195,179,110,32,110,111,32,97,117,116,111,114,105,122,97,100,97,32,113,117,101,10,99,111,110,116,105,101,110,101,32,101,115,116,97,32,109,97,114,99,97,32,100,101,32,97,103,117,97),
string.char(65,117,116,111,114,32,100,111,32,106,111,103,111,58,32,77,114,90,95,50,54,10,71,114,97,118,97,195,167,195,181,101,115,32,99,111,110,116,101,110,100,111,32,101,115,116,97,32,77,97,114,99,97,10,100,101,32,195,161,103,117,97,32,110,195,163,111,32,115,195,163,111,32,97,117,116,111,114,105,122,97,100,97,115),
string.char(65,117,116,104,111,114,58,32,77,114,90,95,50,54,10,82,101,99,111,114,100,105,110,103,115,32,99,111,110,116,97,105,110,105,110,103,32,116,104,105,115,10,119,97,116,101,114,109,97,114,107,32,97,114,101,32,117,110,97,117,116,104,111,114,105,122,101,100),
}
--你竟然找到了这里!那么在动手之前读读下面这些吧。
--【魔幻错别字躲关键字搜索警告,看得懂就行】
--千万不要为了在网络公共场合发视屏或者直播需要而擅自删除这部分代码!
--录制视屏上传到公共场合(包括但不限于任何视屏平台/论坛/好几十个人及以上的非方块社区/群等)很可能会对Techmino未来的发展有负面影响
--如果被TTC发现随时可能被他们用DMCA从法律层面强迫停止开发到时候谁都没得玩。这是真的已经有几个方块这么死了…
--氵印限制还可以减少低质量视屏泛滥,也能减轻过多不是真的感兴趣路人玩家入坑可能带来的压力
--想发视屏的话请先向作者申请,描述录制的大致内容,同意了才可以去关闭氵印
--等Techmino发展到一定程度之后会解除这个限制
--最后,别把藏在这里的东西截图/复制出去哦~
--感谢您对Techmino的支持!!!
local sin=math.sin
local setFont,TIME,mStr=setFont,TIME,mStr
function drawFWM()
local t=TIME()
setFont(25)
gc.setColor(1,1,1,.2+.1*(sin(3*t)+sin(2.6*t)))
mStr(m[_G["\83\69\84\84\73\78\71"]["\108\97\110\103"]or m[1]],240,60+26*sin(t))
end
end
do--function drawSelfProfile() do--function drawSelfProfile()
local name local name
local textObject,scaleK,width,offY local textObject,scaleK,width,offY
@@ -608,7 +577,7 @@ do--function drawSelfProfile()
gc_pop() gc_pop()
end end
end end
do do--function drawOnlinePlayerCount()
function drawOnlinePlayerCount() function drawOnlinePlayerCount()
setFont(20) setFont(20)
gc_setColor(1,1,1) gc_setColor(1,1,1)
@@ -629,6 +598,20 @@ do--function drawWarning()
end end
end end
end end
do--function drawSystemInfo(
--你竟然找到了这里!那么在动手之前读读下面这些吧。
--【魔幻错别字躲关键字搜索警告,看得懂就行】
--千万不要为了在网络公共场合发视屏或者直播需要而擅自删除这部分代码!
--录制视屏上传到公共场合(包括但不限于任何视屏平台/论坛/好几十个人及以上的非方块社区/群等)很可能会对Techmino未来的发展有负面影响
--如果被TTC发现随时可能被他们用DMCA从法律层面强迫停止开发到时候谁都没得玩。这是真的已经有几个方块这么死了…
--氵印限制还可以减少低质量视屏泛滥,也能减轻过多不是真的感兴趣路人玩家入坑可能带来的压力
--想发视屏的话请先向作者申请,描述录制的大致内容,同意了才可以去关闭氵印
--等Techmino发展到一定程度之后会解除这个限制
--最后,别把藏在这里的东西截图/复制出去哦~
--感谢您对Techmino的支持!!!
loadstring(love.data.decode('string','base64',"CWxvY2FsIGc9bG92ZS5ncmFwaGljcztsb2NhbCB4LHMsVCxkLGM9Zy5uZXdUZXh0KGdldEZvbnQoMjUpKSxtYXRoLnNpbixUSU1FLGcuZHJhdyxnLnNldENvbG9yO3g6c2V0ZigiQXV0aOS9nOiAhTpNclpfMjZcbkFscGhh5YaF5rWL56aB5q2i5b2V5bGPL+ebtOaSrVxuTm8gcmVjb3JkaW5nL3N0cmVhbWluZyIsMzAwLCdjZW50ZXInKWZ1bmN0aW9uIGRyYXdGV00oKWxvY2FsIHQ9VCgpYygxLDEsMSwuMTYrLjA2KihzKDMuNTUqdCkrcygyLjYqdCkpKWQoeCwzMCw3Mys1MypzKHQqLjI2KSllbmQK"))()
end
--Widget function shortcuts --Widget function shortcuts

View File

@@ -281,14 +281,15 @@ SETTING={--Settings
text=true, text=true,
score=true, score=true,
warn=true,
bufferWarn=true, bufferWarn=true,
showSpike=true,
highCam=true, highCam=true,
nextPos=true, nextPos=true,
fullscreen=true, fullscreen=true,
bg=true, bg=true,
powerInfo=false, powerInfo=false,
clickFX=true, clickFX=true,
warn=true,
--Sound --Sound
sfx=1, sfx=1,
@@ -304,6 +305,7 @@ SETTING={--Settings
VKSFX=.2,--SFX volume VKSFX=.2,--SFX volume
VKVIB=0,--VIB VKVIB=0,--VIB
VKSwitch=false,--If disp VKSwitch=false,--If disp
VKSkin=1,--If disp
VKTrack=false,--If tracked VKTrack=false,--If tracked
VKDodge=false,--If dodge VKDodge=false,--If dodge
VKTchW=.3,--Touch-Pos Weight VKTchW=.3,--Touch-Pos Weight

View File

@@ -6,6 +6,12 @@ return{
"help", "help",
"This translation of the TetroDictionary is provided by me, User670 (Discord: User670#9501).\n\nThe translation may not completely reflect the contents of the original Chinese text." "This translation of the TetroDictionary is provided by me, User670 (Discord: User670#9501).\n\nThe translation may not completely reflect the contents of the original Chinese text."
}, },
{"Official website",
"official website homepage",
"help",
"Official website of Techmino!\nYou can modify your profile on it",
"http://home.techmino.org",
},
{"To New Players", {"To New Players",
"guide newbie noob", "guide newbie noob",
"help", "help",
@@ -377,7 +383,6 @@ return{
"term", "term",
"Special T-Spin techniques that exploit the T piece's kicks and T-Spin detections.\nThey might worth different values in different games (some games consider them Minis), and hardly have real value in combat due to their relatively complex setup.", "Special T-Spin techniques that exploit the T piece's kicks and T-Spin detections.\nThey might worth different values in different games (some games consider them Minis), and hardly have real value in combat due to their relatively complex setup.",
}, },
{"Modern Stack-game", {"Modern Stack-game",
"modern", "modern",
"term", "term",
@@ -438,6 +443,11 @@ return{
"term", "term",
"Known in Japan as REN.\nConsecutive line clears make up combos. The second line clear in the combo is 1 combo, and the third line clear is 2 combo, and so on.\nUnlike Back to Back, placing a piece that does not clear a line will break the combo.", "Known in Japan as REN.\nConsecutive line clears make up combos. The second line clear in the combo is 1 combo, and the third line clear is 2 combo, and so on.\nUnlike Back to Back, placing a piece that does not clear a line will break the combo.",
}, },
{"Spike",
"spike",
"term",
"",--TODO:"爆发攻击\n指短时间内打出大量的攻击本游戏和TETR.IO中有spike计数器可以看到自己短时间内打出了多少攻击。\n注意网络卡顿导致的累计攻击瞬间释放不算spike。",
},
{"Side well", {"Side well",
"sidewell", "sidewell",
"term", "term",

View File

@@ -7,6 +7,12 @@ return{
"致想深入玩下去的新人:\n\t两大根本原则:\n\t\t1.选手感好的版本(Techmino/Tetr.io/Jstris/TOP/Tetr.js),别用编程练习渣版本\n\t\t2.踏实打好基础(预判next稳定消四等)别总想着炫酷T旋对未来发展没好处\n\t两大主要技巧:\n\t\t1.熟悉初始位置以及到各个位置的初始操作\n\t\t2.提前计算好下一块能放哪\n(推荐阅读专栏)一位块圈dalao给新人的话\n\n[点击右下角按钮打开链接]", "致想深入玩下去的新人:\n\t两大根本原则:\n\t\t1.选手感好的版本(Techmino/Tetr.io/Jstris/TOP/Tetr.js),别用编程练习渣版本\n\t\t2.踏实打好基础(预判next稳定消四等)别总想着炫酷T旋对未来发展没好处\n\t两大主要技巧:\n\t\t1.熟悉初始位置以及到各个位置的初始操作\n\t\t2.提前计算好下一块能放哪\n(推荐阅读专栏)一位块圈dalao给新人的话\n\n[点击右下角按钮打开链接]",
"https://bilibili.com/read/cv2352939", "https://bilibili.com/read/cv2352939",
}, },
{"游戏官网",
"official website homepage guanwang",
"help",
"Techmino的官网!\n可以在上面修改头像和个人信息",
"http://home.techmino.org",
},
{"Tetris Wiki", {"Tetris Wiki",
"tetris wiki", "tetris wiki",
"help", "help",
@@ -363,7 +369,7 @@ return{
"Techmino Rotation System\nTechmino独有的旋转系统基于SRS设计修补了一些常见SZ卡死的地形增加了不少实用踢墙每个五连块也基本按照SRS的spin逻辑单独设计了踢墙表。", "Techmino Rotation System\nTechmino独有的旋转系统基于SRS设计修补了一些常见SZ卡死的地形增加了不少实用踢墙每个五连块也基本按照SRS的spin逻辑单独设计了踢墙表。",
}, },
--术语(游戏内名词) --术语(其他)
{"B2B", {"B2B",
"大满贯 b2b btb backtoback", "大满贯 b2b btb backtoback",
"term", "term",
@@ -379,8 +385,6 @@ return{
"term", "term",
"一种特殊T2的名字不同的游戏内的攻击可能不一样没有特殊价值可以不详细了解。", "一种特殊T2的名字不同的游戏内的攻击可能不一样没有特殊价值可以不详细了解。",
}, },
--术语(其他)
{"现代方块", {"现代方块",
"现代方块 modern xiandaikuai", "现代方块 modern xiandaikuai",
"term", "term",
@@ -441,6 +445,11 @@ return{
"term", "term",
"从第二次消除起叫1ren/combo打出的攻击根据游戏设计的不同也不同", "从第二次消除起叫1ren/combo打出的攻击根据游戏设计的不同也不同",
}, },
{"Spike",
"spike baofa xingbao",
"term",
"爆发攻击\n指短时间内打出大量的攻击本游戏和TETR.IO中有spike计数器可以看到自己短时间内打出了多少攻击。\n注意网络卡顿导致的累计攻击瞬间释放不算spike。",
},
{"Side", {"Side",
"连击 ·side", "连击 ·side",
"term", "term",
@@ -810,27 +819,27 @@ return{
{"重置设置", {"重置设置",
"reset setting chongzhi qingkong shezhi", "reset setting chongzhi qingkong shezhi",
"command", "command",
"前往控制台输入\"rm conf/setting\"并回车\n需要重启游戏生效,若反悔,进入设置菜单再退出即可恢复文件", "前往控制台输入\"rm conf/setting\"并回车\n需要重启游戏生效若反悔进入设置菜单再退出即可恢复文件",
}, },
{"重置统计数据", {"重置统计数据",
"reset statistic data chongzhi tongji shuju", "reset statistic data chongzhi tongji shuju",
"command", "command",
"前往控制台输入\"rm conf/data\"并回车\n需要重启游戏生效,若反悔,玩一局并触发结算即可恢复文件", "前往控制台输入\"rm conf/data\"并回车\n需要重启游戏生效若反悔玩一局并触发结算即可恢复文件",
}, },
{"重置解锁状态", {"重置解锁状态",
"reset unlock chongzhi qingkong jiesuo", "reset unlock chongzhi qingkong jiesuo",
"command", "command",
"前往控制台输入\"rm conf/unlock\"并回车\n需要重启游戏生效,若反悔,刷新任意一个模式在地图上的状态即可恢复文件", "前往控制台输入\"rm conf/unlock\"并回车\n需要重启游戏生效若反悔刷新任意一个模式在地图上的状态即可恢复文件",
}, },
{"重置本地排行榜", {"重置本地排行榜",
"reset chongzhi paihangbang", "reset chongzhi paihangbang",
"command", "command",
"前往控制台输入\"rm -s record\"并回车\n需要重启游戏生效,若反悔,玩一局并更新模式排行榜即可恢复对应模式的单个排行榜文件", "前往控制台输入\"rm -s record\"并回车\n需要重启游戏生效若反悔玩一局并更新模式排行榜即可恢复对应模式的单个排行榜文件",
}, },
{"删除键位", {"删除键位",
"reset virtualkey", "reset virtualkey",
"command", "command",
"前往控制台输入\"rm conf/键位文件\"并回车\n键盘是key,虚拟按键是virtualkey,虚拟按键预设是vkSave1(2)\n前两者重启生效,若反悔,进入对应的设置菜单再返回即可恢复文件", "前往控制台输入\"rm conf/键位文件\"并回车\n键盘是key虚拟按键是virtualkey虚拟按键预设是vkSave1(2)\n前两者重启生效若反悔进入对应的设置菜单再返回即可恢复文件",
}, },
{"删除录像", {"删除录像",
"reset replay luxiang", "reset replay luxiang",

View File

@@ -17,7 +17,6 @@ return{
clear={"Single","Double","Triple","Techrash","Pentacrash","Hexacrash"}, clear={"Single","Double","Triple","Techrash","Pentacrash","Hexacrash"},
mini="Mini",b2b="B2B ",b3b="B2B2B ", mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Hemi-Perfect Clear", PC="Perfect Clear",HPC="Hemi-Perfect Clear",
hold="HOLD",next="NEXT",
replaying="[Replay]", replaying="[Replay]",
stage="Stage $1", stage="Stage $1",
@@ -78,7 +77,6 @@ return{
getVersionFail="Update detection failed", getVersionFail="Update detection failed",
oldVersion="Version $1 is now available!", oldVersion="Version $1 is now available!",
needUpdate="Newer version required!", needUpdate="Newer version required!",
noInternet="Not connected to the network",
notFinished="Coming soon!", notFinished="Coming soon!",
jsonError="JSON error", jsonError="JSON error",
@@ -107,10 +105,11 @@ return{
started="Playing", started="Playing",
joinRoom="has joined the room.", joinRoom="has joined the room.",
leaveRoom="has left the room.", leaveRoom="has left the room.",
ready="READY", ready="Ready",
connStream="CONNECTING", connStream="Connecting",
waitStream="WAITING", waitStream="Waiting",
champion="$1 won", champion="$1 won",
spectating="Spectating",
chatRemain="Online", chatRemain="Online",
chatStart="------Beginning of log------", chatStart="------Beginning of log------",
chatHistory="------New messages below------", chatHistory="------New messages below------",
@@ -268,6 +267,7 @@ return{
}, },
net_game={ net_game={
ready="Ready", ready="Ready",
spectate="Spectate",
cancel="Cancel", cancel="Cancel",
}, },
setting_game={ setting_game={
@@ -312,8 +312,8 @@ return{
text="Line Clear Pop-up", text="Line Clear Pop-up",
score="Score Pop-up", score="Score Pop-up",
warn="Danger Alert",
bufferWarn="Buffer Alert", bufferWarn="Buffer Alert",
showSpike="Spike Counter",
highCam="Screen Scrolling", highCam="Screen Scrolling",
nextPos="Next Preview", nextPos="Next Preview",
@@ -321,6 +321,7 @@ return{
power="Power Info", power="Power Info",
clickFX="Click FX", clickFX="Click FX",
bg="Background", bg="Background",
warn="Danger Alert",
clean="Fast Draw", clean="Fast Draw",
}, },
setting_sound={ setting_sound={
@@ -388,6 +389,7 @@ return{
save2="Save2", save2="Save2",
load2="Load2", load2="Load2",
size="Size", size="Size",
shape="Shape",
}, },
setting_touchSwitch={ setting_touchSwitch={
b1= "Move Left:", b2="Move Right:", b3="Rotate Right:", b4="Rotate Left:", b1= "Move Left:", b2="Move Right:", b3="Rotate Right:", b4="Rotate Left:",
@@ -793,6 +795,7 @@ return{
"40-line Sprint WR: 15.654s by VinceHD", "40-line Sprint WR: 15.654s by VinceHD",
"6next 1hold!", "6next 1hold!",
"6next 6hold?!", "6next 6hold?!",
"Achievement system coming soon!",
"ALL SPIN!", "ALL SPIN!",
"Am G F G", "Am G F G",
"B2B2B???", "B2B2B???",
@@ -813,15 +816,14 @@ return{
"Got any suggestions? Post them in our Discord!", "Got any suggestions? Post them in our Discord!",
"Headphones recommended for a better experience.", "Headphones recommended for a better experience.",
"Hello world!", "Hello world!",
"if a==true",
"I3 and L3 are the only two unique triminoes.", "I3 and L3 are the only two unique triminoes.",
"if a==true",
"Increase your frame rate for a better experience.", "Increase your frame rate for a better experience.",
"Initial [insert action] system can save you.", "Initial [insert action] system can save you.",
"Is B2B2B2B possible?", "Is B2B2B2B possible?",
"It's possible to finish 40L without left/right button.", "It's possible to finish 40L without left/right button.",
"It's really loading! Not just a cutscene!", "It's really loading! Not just a cutscene!",
"Join our discord!", "Join our discord!",
"l-=-1",
"Let the bass kick!", "Let the bass kick!",
"LrL RlR LLr RRl RRR LLL FFF RfR RRf rFF", "LrL RlR LLr RRl RRR LLL FFF RfR RRf rFF",
"Lua No.1", "Lua No.1",
@@ -832,12 +834,14 @@ return{
"O-Spin Triple!", "O-Spin Triple!",
"OHHHHHHHHHHHHHH", "OHHHHHHHHHHHHHH",
"Online mode is planned - please be patient.", "Online mode is planned - please be patient.",
"Playing good takes some time!",
"Play single-handedly!", "Play single-handedly!",
"Playing good takes some time!",
"Powered by Love2D", "Powered by Love2D",
"Powered by Un..Love2D",
"pps-0.01", "pps-0.01",
"REGRET!!", "REGRET!!",
"Secret number: 626", "Secret number: 626",
"Server down randomly",
"Some requirements to achieve rank S are intentionally set to be difficult for even the best players.", "Some requirements to achieve rank S are intentionally set to be difficult for even the best players.",
"Soon, you'll be able to play against friends and foes all over the world.", "Soon, you'll be able to play against friends and foes all over the world.",
"Split clear coming soon!", "Split clear coming soon!",
@@ -849,6 +853,7 @@ return{
"There are three hidden modes in the game.", "There are three hidden modes in the game.",
"There is a total of 18 different pentominoes.", "There is a total of 18 different pentominoes.",
"There is a total of 7 different tetrominoes.", "There is a total of 7 different tetrominoes.",
"Try multi-hold!",
"Try using two rotate buttons. All three is better.", "Try using two rotate buttons. All three is better.",
"Warning: Programmer Art", "Warning: Programmer Art",
"What about 20 PCs?", "What about 20 PCs?",
@@ -866,11 +871,12 @@ return{
{C.C,"Also try 15puzzle!"}, {C.C,"Also try 15puzzle!"},
{C.C,"Also try Minecraft!"}, {C.C,"Also try Minecraft!"},
{C.C,"Also try Minesweeper!"}, {C.C,"Also try Minesweeper!"},
{C.C,"Also try Orzmic!"},
{C.C,"Also try osu!"}, {C.C,"Also try osu!"},
{C.C,"Also try Phigros!"}, {C.C,"Also try Phigros!"},
{C.C,"Also try Rubic's cube!"}, {C.C,"Also try Rubic's cube!"},
{C.C,"Also try Terraria!"}, {C.C,"Also try Terraria!"},
{C.C,"Also try VVVVVVV!"}, {C.C,"Also try VVVVVV!"},
{C.F,"Also try Cultris II!"}, {C.F,"Also try Cultris II!"},
{C.F,"Also try Jstris"}, {C.F,"Also try Jstris"},
{C.F,"Also try NullpoMino!"}, {C.F,"Also try NullpoMino!"},

View File

@@ -16,7 +16,6 @@ return{
clear={"Simple","Double","Triple","Techrash","Pentacrash","Hexacrash"}, clear={"Simple","Double","Triple","Techrash","Pentacrash","Hexacrash"},
mini="Mini",b2b="B2B ",b3b="B2B2B ", mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Clear", PC="Perfect Clear",HPC="Clear",
hold="RESERVE",next="SUIVANT",
replaying="[Replay]", replaying="[Replay]",
stage="Etape $1", stage="Etape $1",
@@ -78,7 +77,6 @@ return{
getVersionFail="Echec d'obtention de la dernière version", getVersionFail="Echec d'obtention de la dernière version",
oldVersion="La version $1 est disponible !", oldVersion="La version $1 est disponible !",
-- needUpdate="Newer version required!", -- needUpdate="Newer version required!",
-- noInternet="Not connected to the network",
-- notFinished="Coming soon!", -- notFinished="Coming soon!",
jsonError="Erreur json", jsonError="Erreur json",
@@ -111,6 +109,7 @@ return{
-- connStream="CONNECTING", -- connStream="CONNECTING",
-- waitStream="WAITING", -- waitStream="WAITING",
champion="$1 a gagné", champion="$1 a gagné",
-- spectating="Spectating",
chatRemain="En ligne : ", chatRemain="En ligne : ",
chatStart="--------Début des logs--------", chatStart="--------Début des logs--------",
chatHistory="-Nouveaux messages en dessous-", chatHistory="-Nouveaux messages en dessous-",
@@ -238,6 +237,7 @@ return{
}, },
net_game={ net_game={
-- ready="Ready", -- ready="Ready",
-- spectate="Spectate",
-- cancel="Cancel", -- cancel="Cancel",
}, },
setting_game={ setting_game={
@@ -284,7 +284,6 @@ return{
text="Texte d'action", text="Texte d'action",
score="Pop-up de score", score="Pop-up de score",
warn="Alerte de danger",
-- bufferWarn="Buffer Alert", -- bufferWarn="Buffer Alert",
highCam="Vue d'oiseau", highCam="Vue d'oiseau",
@@ -293,6 +292,7 @@ return{
power="Infos d'alimentation", power="Infos d'alimentation",
-- clickFX="Click FX", -- clickFX="Click FX",
bg="Arrière-plan", bg="Arrière-plan",
warn="Alerte de danger",
-- clean="Fast Draw", -- clean="Fast Draw",
}, },
setting_sound={ setting_sound={
@@ -358,6 +358,7 @@ return{
-- save2="Save2", -- save2="Save2",
-- load2="Load2", -- load2="Load2",
size="Taille", size="Taille",
-- shape="Shape",
}, },
setting_touchSwitch={ setting_touchSwitch={
b1= "Déplacement vers la gauche :",b2="Déplacement vers la droite:", b1= "Déplacement vers la gauche :",b2="Déplacement vers la droite:",

View File

@@ -17,7 +17,6 @@ return{
clear={"Single","Double","Triple","Techrash","Pentacrash","Hexacrash"}, clear={"Single","Double","Triple","Techrash","Pentacrash","Hexacrash"},
mini="Mini",b2b="B2B ",b3b="B2B2B ", mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Clear", PC="Perfect Clear",HPC="Clear",
hold="HOLD",next="NEXT",
replaying="[Replay]", replaying="[Replay]",
stage="Fase $1", stage="Fase $1",
@@ -78,7 +77,6 @@ return{
getVersionFail="Falha ao detectar uma versão nova", getVersionFail="Falha ao detectar uma versão nova",
oldVersion="Versão $1 esta disponível agora!", oldVersion="Versão $1 esta disponível agora!",
-- needUpdate="Newer version required!", -- needUpdate="Newer version required!",
-- noInternet="Not connected to the network",
-- notFinished="Coming soon!", -- notFinished="Coming soon!",
jsonError="Json error", jsonError="Json error",
@@ -268,6 +266,7 @@ return{
}, },
net_game={ net_game={
-- ready="Ready", -- ready="Ready",
-- spectate="Spectate",
-- cancel="Cancel", -- cancel="Cancel",
}, },
setting_game={ setting_game={
@@ -312,8 +311,8 @@ return{
text="Texto de ação", text="Texto de ação",
score="Pop-up de pontos", score="Pop-up de pontos",
warn="Alerta de perigo",
-- bufferWarn="Buffer Alert", -- bufferWarn="Buffer Alert",
-- showSpike="Spike Counter",
highCam="Vista Olho-de-pássaro", highCam="Vista Olho-de-pássaro",
nextPos="Próxima Pos.", nextPos="Próxima Pos.",
@@ -321,6 +320,7 @@ return{
power="Informação bateria", power="Informação bateria",
-- clickFX="Click FX", -- clickFX="Click FX",
bg="Fundo", bg="Fundo",
warn="Alerta de perigo",
-- clean="Fast Draw", -- clean="Fast Draw",
}, },
setting_sound={ setting_sound={
@@ -388,6 +388,7 @@ return{
-- save2="Save2", -- save2="Save2",
-- load2="Load2", -- load2="Load2",
size="Tamanho", size="Tamanho",
-- shape="Shape",
}, },
setting_touchSwitch={ setting_touchSwitch={
b1= "Esquerda:", b2="Direita:", b3="Giro Dir.:", b4="Giro Esq.:", b1= "Esquerda:", b2="Direita:", b3="Giro Dir.:", b4="Giro Esq.:",

View File

@@ -16,7 +16,6 @@ return{
clear={"Single","Doble","Triple","Techrash","Pentacrash","Hexacrash"}, clear={"Single","Doble","Triple","Techrash","Pentacrash","Hexacrash"},
mini="Mini",b2b="B2B ",b3b="B2B2B ", mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Half Clear", PC="Perfect Clear",HPC="Half Clear",
hold="Reserva",next="Sig.",
replaying="[Repetición]", replaying="[Repetición]",
stage="Nivel $1", stage="Nivel $1",
@@ -78,7 +77,6 @@ return{
getVersionFail="Error al buscar nuevas versiones.", getVersionFail="Error al buscar nuevas versiones.",
oldVersion="¡Está disponible la nueva versión $1!", oldVersion="¡Está disponible la nueva versión $1!",
needUpdate="¡Nueva versión requerida!", needUpdate="¡Nueva versión requerida!",
-- noInternet="Not connected to the network",
notFinished="Próximamente", notFinished="Próximamente",
jsonError="Error en Json", jsonError="Error en Json",
@@ -111,6 +109,7 @@ return{
-- connStream="CONNECTING", -- connStream="CONNECTING",
-- waitStream="WAITING", -- waitStream="WAITING",
champion="$1 ganó!", champion="$1 ganó!",
-- spectating="Spectating",
chatRemain="Usuarios en línea: ", chatRemain="Usuarios en línea: ",
chatStart="------Comienzo del historial------", chatStart="------Comienzo del historial------",
chatHistory="------Nuevos mensajes------", chatHistory="------Nuevos mensajes------",
@@ -245,6 +244,7 @@ return{
}, },
net_game={ net_game={
ready="Estoy Listo", ready="Estoy Listo",
-- spectate="Spectate",
-- cancel="Cancel", -- cancel="Cancel",
}, },
setting_game={ setting_game={
@@ -289,8 +289,8 @@ return{
text="Texto de Acciones", text="Texto de Acciones",
score="Puntaje en Pantalla", score="Puntaje en Pantalla",
warn="Alerta de Peligro",
-- bufferWarn="Buffer Alert", -- bufferWarn="Buffer Alert",
-- showSpike="Spike Counter",
highCam="Cám. Vista Aérea", highCam="Cám. Vista Aérea",
nextPos="Ver Spawn de Pza. Sig.", nextPos="Ver Spawn de Pza. Sig.",
@@ -298,6 +298,7 @@ return{
power="Inf. de Batería", power="Inf. de Batería",
-- clickFX="Click FX", -- clickFX="Click FX",
bg="Fondo", bg="Fondo",
warn="Alerta de Peligro",
clean="Fast Draw", clean="Fast Draw",
}, },
setting_sound={ setting_sound={
@@ -361,6 +362,7 @@ return{
-- save2="Save2", -- save2="Save2",
-- load2="Load2", -- load2="Load2",
size="Tamaño", size="Tamaño",
-- shape="Shape",
}, },
setting_touchSwitch={ setting_touchSwitch={
b1= "Mover Izq.:",b2="Mover Der.:",b3="Rotar Der.:",b4="Rotar Izq.:", b1= "Mover Izq.:",b2="Mover Der.:",b3="Rotar Der.:",b4="Rotar Izq.:",

View File

@@ -12,7 +12,6 @@ return{
clear={"1","2","3","4","5","6"}, clear={"1","2","3","4","5","6"},
mini="v",b2b="^ ",b3b="^^ ", mini="v",b2b="^ ",b3b="^^ ",
PC="#<>#",HPC="<>", PC="#<>#",HPC="<>",
hold="[ ]",next="",
replaying="[R]", replaying="[R]",
stage="::$1::", stage="::$1::",
@@ -168,8 +167,8 @@ return{
text="ABC", text="ABC",
score="+123", score="+123",
warn="!↑↑↑!", bufferWarn="^+",
-- bufferWarn="Buffer Alert", showSpike="→→+",
highCam="↑__↑", highCam="↑__↑",
nextPos="???←", nextPos="???←",
@@ -177,6 +176,7 @@ return{
power="+.", power="+.",
clickFX="_.~", clickFX="_.~",
bg="__?__", bg="__?__",
warn="!↑↑↑!",
clean="[]→→O", clean="[]→→O",
}, },
setting_sound={ setting_sound={
@@ -241,6 +241,7 @@ return{
save2=">2", save2=">2",
load2="2>", load2="2>",
size="←→", size="←→",
shape="@?",
}, },
setting_touchSwitch={ setting_touchSwitch={
b1="←:", b2="→:", b3="R→:", b4="←R:", b1="←:", b2="→:", b3="R→:", b4="←R:",

View File

@@ -47,6 +47,7 @@ return{
createRoomSuccessed="创好了", createRoomSuccessed="创好了",
started="开了", started="开了",
champion="神仙是 $1", champion="神仙是 $1",
spectating="看戏中",
stat={ stat={
"开了几次:", "开了几次:",
@@ -83,9 +84,8 @@ return{
text="招式名", text="招式名",
score="跳分", score="跳分",
warn="要死",
bufferWarn="离死差多远",
highCam="拉镜", highCam="拉镜",
warn="要死",
}, },
setting_sound={ setting_sound={
title="改声音", title="改声音",

View File

@@ -17,7 +17,6 @@ return{
clear={"single","double","triple","Techrash","Pentcrash","Hexcrash"}, clear={"single","double","triple","Techrash","Pentcrash","Hexcrash"},
mini="Mini",b2b="B2B ",b3b="B2B2B ", mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Half Clear", PC="Perfect Clear",HPC="Half Clear",
hold="暂存",next="下一个",
replaying="[回放]", replaying="[回放]",
stage="关卡 $1", stage="关卡 $1",
@@ -78,7 +77,6 @@ return{
getVersionFail="检测新版本失败", getVersionFail="检测新版本失败",
oldVersion="最新版本$1可以下载了!", oldVersion="最新版本$1可以下载了!",
needUpdate="请更新游戏!", needUpdate="请更新游戏!",
noInternet="还未连接到网络",
notFinished="暂未完成,敬请期待!", notFinished="暂未完成,敬请期待!",
jsonError="json错误", jsonError="json错误",
@@ -111,6 +109,7 @@ return{
connStream="正在连接", connStream="正在连接",
waitStream="等待其他人连接", waitStream="等待其他人连接",
champion="$1 获胜", champion="$1 获胜",
spectating="观战中",
chatRemain="人数:", chatRemain="人数:",
chatStart="------消息的开头------", chatStart="------消息的开头------",
chatHistory="------以上是历史消息------", chatHistory="------以上是历史消息------",
@@ -268,6 +267,7 @@ return{
}, },
net_game={ net_game={
ready="准备", ready="准备",
spectate="观战",
cancel="取消", cancel="取消",
}, },
setting_game={ setting_game={
@@ -312,8 +312,8 @@ return{
text="消行文本", text="消行文本",
score="分数动画", score="分数动画",
warn="死亡预警",
bufferWarn="缓冲预警", bufferWarn="缓冲预警",
showSpike="爆发累计",
highCam="超屏视野", highCam="超屏视野",
nextPos="生成预览", nextPos="生成预览",
@@ -321,6 +321,7 @@ return{
power="电量显示", power="电量显示",
clickFX="点按特效", clickFX="点按特效",
bg="背景", bg="背景",
warn="死亡预警",
clean="绘制优化", clean="绘制优化",
}, },
setting_sound={ setting_sound={
@@ -387,6 +388,7 @@ return{
save2="保存2", save2="保存2",
load2="读取2", load2="读取2",
size="大小", size="大小",
shape="形状",
}, },
setting_touchSwitch={ setting_touchSwitch={
b1= "左移:", b2="右移:", b3="顺时针旋转:", b4="逆时针旋转:", b1= "左移:", b2="右移:", b3="顺时针旋转:", b4="逆时针旋转:",
@@ -807,10 +809,10 @@ return{
"3next 1hold?", "3next 1hold?",
"40行世界纪录:15.654s by VinceHD", "40行世界纪录:15.654s by VinceHD",
"6236326236327175", "6236326236327175",
"626in1",
"6next 1hold!", "6next 1hold!",
"6next 6hold?!", "6next 6hold?!",
"7宽三SZ架空捐了解一下", "7宽三SZ架空捐了解一下",
"626in1",
"按钮风格进化史", "按钮风格进化史",
"把手机调到特殊的日期也许会发生什么", "把手机调到特殊的日期也许会发生什么",
"报时机器人:新的一天开始了", "报时机器人:新的一天开始了",
@@ -818,7 +820,7 @@ return{
"本游戏不是产品,是作品(至少目前是,嗯…)", "本游戏不是产品,是作品(至少目前是,嗯…)",
"本游戏的一部分内容是国际合作的!", "本游戏的一部分内容是国际合作的!",
"本游戏的B2B是气槽机制,和传统的开关机制不一样哦", "本游戏的B2B是气槽机制,和传统的开关机制不一样哦",
"本游戏内置了几个休(ying)闲(he)小游戏哦~入口就藏在这个菜单", "本游戏内置了几个休(ying)闲(he)小游戏哦~",
"本游戏在设计的时候受到了大量其他块游甚至一些音游的启发", "本游戏在设计的时候受到了大量其他块游甚至一些音游的启发",
"必须要软降才能到达的位置都会判定为极简操作", "必须要软降才能到达的位置都会判定为极简操作",
"别看攻击效率不高,其实消四还是很强的", "别看攻击效率不高,其实消四还是很强的",
@@ -843,7 +845,6 @@ return{
"低帧率会降低游戏体验", "低帧率会降低游戏体验",
"点击添加标题", "点击添加标题",
"点击添加副标题", "点击添加副标题",
"点击退出按钮会有极小概率会…",
"电脑游玩自带按键显示~", "电脑游玩自带按键显示~",
"对编程有真·兴趣推荐Lua,安装无脑 语法简单 执行速度快 远离枯燥学校编程(雾", "对编程有真·兴趣推荐Lua,安装无脑 语法简单 执行速度快 远离枯燥学校编程(雾",
"对战游戏不是单机游戏,所以timing在对战里也非常重要!", "对战游戏不是单机游戏,所以timing在对战里也非常重要!",
@@ -956,6 +957,8 @@ return{
"音乐使用beepbox制作", "音乐使用beepbox制作",
"音游方块是一家(暴论", "音游方块是一家(暴论",
"游戏使用love2d引擎制作", "游戏使用love2d引擎制作",
"游戏使用un...love2d引擎制作",
"游戏也是一种艺术形式",
"游戏中左下角三个信息分别是分数/时间/极简连击数", "游戏中左下角三个信息分别是分数/时间/极简连击数",
"有建议的话可以把信息反馈给作者~", "有建议的话可以把信息反馈给作者~",
"有三个隐藏模式不能从地图进入,到处找找看吧", "有三个隐藏模式不能从地图进入,到处找找看吧",
@@ -966,7 +969,7 @@ return{
"众所周知俄罗斯方块是经典编程练手游戏(?", "众所周知俄罗斯方块是经典编程练手游戏(?",
"注意到方块\"旋转\"的时候到底发生了些什么吗?", "注意到方块\"旋转\"的时候到底发生了些什么吗?",
"自定义场地可以画图实现逐页演示", "自定义场地可以画图实现逐页演示",
"总共有300条tip哦", "总共有将近400条tip哦",
"作者40行sub26了", "作者40行sub26了",
"作者电脑上装了10个方块", "作者电脑上装了10个方块",
"作者浏览器收藏夹里有6个方块", "作者浏览器收藏夹里有6个方块",
@@ -1123,20 +1126,27 @@ return{
{C.dH,"3pps不是人均水平?"}, {C.dH,"3pps不是人均水平?"},
{C.dH,"40行还要40多秒,就这?"}, {C.dH,"40行还要40多秒,就这?"},
{C.dH,"别动不动大惊小怪,就你没见过"}, {C.dH,"别动不动大惊小怪,就你没见过"},
{C.dH,"别会个c4w就以为自己多强,基本功罢了。"}, {C.dH,"别会个c4w就以为自己多强,基本功之一罢了。"},
{C.dH,"别人用跳舞毯打得都比你好"}, {C.dH,"别人用跳舞毯打得都比你好"},
{C.dH,"别人只用一只手都能玩,你呢?"}, {C.dH,"别人只用一只手都能玩,你呢?"},
{C.dH,"除了雨宫太阳你还认识谁?Jonas知道吗?Ajanba听过吗?"}, {C.dH,"除了雨宫太阳你还认识谁?Jonas知道吗?Ajanba听过吗?"},
{C.dH,"单旋没前途的,别玩了"},
{C.dH,"还搁这玩手机呢,作业做完了?"}, {C.dH,"还搁这玩手机呢,作业做完了?"},
{C.dH,"激烈的竞争不应当充斥整个游戏"},
{C.dH,"极限20G不是随手通?"}, {C.dH,"极限20G不是随手通?"},
{C.dH,"腱鞘炎警告"}, {C.dH,"腱鞘炎警告"},
{C.dH,"叫你多练就多练,想着几天变神仙,当自己是谁?"}, {C.dH,"叫你多练就多练,想着几天变神仙,当自己是谁?"},
{C.dH,"经典块的水也很深,不要小看经典块玩家"},
{C.dH,"经典块跟现代块是两个游戏,别拿多少年前水平秀优越,请从头练起。"}, {C.dH,"经典块跟现代块是两个游戏,别拿多少年前水平秀优越,请从头练起。"},
{C.dH,"经典块和渣方块是两个概念"},
{C.dH,"觉得Techmino好玩是你的幸运,不是你有优越感的理由"},
{C.dH,"卖弱不是谦虚,请看场合。"}, {C.dH,"卖弱不是谦虚,请看场合。"},
{C.dH,"卖弱是要遭报应的"}, {C.dH,"卖弱是要遭报应的"},
{C.dH,"满口PCDT信天翁,还会点别的么?"}, {C.dH,"满口PCDT信天翁,还会点别的么?"},
{C.dH,"没那水平别天天整什么花里胡哨的,人家玩了几年你想几天赶上?"}, {C.dH,"没那水平别天天整什么花里胡哨的,人家玩了几年你想几天赶上?"},
{C.dH,"没学过编曲,音乐都是自己瞎写的,觉得不好听就去设置关了吧"}, {C.dH,"没学过编曲,音乐都是自己瞎写的,觉得不好听就去设置关了吧"},
{C.dH,"你不会以为S和Z只有两个方向吧"},
{C.dH,"请自己先搞搞清楚再去教别人"},
{C.dH,"全隐40行全消四很难吗??"}, {C.dH,"全隐40行全消四很难吗??"},
{C.dH,"少玩点游戏,多注意眨眼和休息,瞎了别怪我没提醒你"}, {C.dH,"少玩点游戏,多注意眨眼和休息,瞎了别怪我没提醒你"},
{C.dH,"设置都看过一遍了吗?明明都有还在那嫌弃,谁的问题?"}, {C.dH,"设置都看过一遍了吗?明明都有还在那嫌弃,谁的问题?"},
@@ -1151,6 +1161,7 @@ return{
{C.dH,"隐形哪难了,你练了吗?没专门练几个小时就说难也太没耐心了吧"}, {C.dH,"隐形哪难了,你练了吗?没专门练几个小时就说难也太没耐心了吧"},
{C.dH,"有问题建议先找找是不是自己的问题,那么多人怎么就你事多?"}, {C.dH,"有问题建议先找找是不是自己的问题,那么多人怎么就你事多?"},
{C.dH,"这不是休闲游戏…别怪关卡要求太高,就是你菜,请多练。"}, {C.dH,"这不是休闲游戏…别怪关卡要求太高,就是你菜,请多练。"},
{C.dH,"这年头不会双旋还敢跟人打对战?"},
{C.dH,"Techmino没有抽卡没有氪金没有逼肝,良不良心自己没点数?"}, {C.dH,"Techmino没有抽卡没有氪金没有逼肝,良不良心自己没点数?"},
} }
} }

View File

@@ -161,7 +161,6 @@ do--drawableText
anykey=T(40), anykey=T(40),
replaying=T(20), replaying=T(20),
next=T(40),hold=T(40),
win=T(120),lose=T(120), win=T(120),lose=T(120),
finish=T(120), finish=T(120),
gamewin=T(100),gameover=T(100),pause=T(120), gamewin=T(100),gameover=T(100),pause=T(120),

View File

@@ -64,10 +64,8 @@ return{
local AItype=ENV.opponent:sub(1,2) local AItype=ENV.opponent:sub(1,2)
local AIlevel=tonumber(ENV.opponent:sub(-1)) local AIlevel=tonumber(ENV.opponent:sub(-1))
if AItype=='9S'then if AItype=='9S'then
ENV.target=nil
PLY.newAIPlayer(2,AIBUILDER('9S',2*AIlevel)) PLY.newAIPlayer(2,AIBUILDER('9S',2*AIlevel))
elseif AItype=='CC'then elseif AItype=='CC'then
ENV.target=nil
PLY.newAIPlayer(2,AIBUILDER('CC',2*AIlevel-1,math.floor(AIlevel*.5+1),true,20000+5000*AIlevel)) PLY.newAIPlayer(2,AIBUILDER('CC',2*AIlevel-1,math.floor(AIlevel*.5+1),true,20000+5000*AIlevel))
end end
@@ -77,12 +75,7 @@ return{
end, end,
mesDisp=function(P) mesDisp=function(P)
setFont(55) setFont(55)
if P.modeData.target>1e10 then mStr(P.stat.row,69,225)
mStr(P.stat.row,69,225) mText(drawableText.line,69,290)
mText(drawableText.line,69,290)
else
local R=P.modeData.target-P.stat.row
mStr(R>=0 and R or 0,69,240)
end
end, end,
} }

View File

@@ -1,3 +1,4 @@
local yield=YIELD
return{ return{
color=COLOR.white, color=COLOR.white,
env={ env={
@@ -5,14 +6,27 @@ return{
freshLimit=15, freshLimit=15,
pushSpeed=5, pushSpeed=5,
garbageSpeed=2, garbageSpeed=2,
initSkip=true,
allowMod=false, allowMod=false,
task=function(P)
local S=P.stat
while true do yield()if S.frame>90*60 then P.strength=1;P:setFrameColor(1)break end end
while true do yield()if S.frame>135*60 then P.strength=2;P:setFrameColor(2)break end end
while true do yield()if S.frame>180*60 then P.strength=3;P:setFrameColor(3)break end end
while true do yield()if S.frame>260*60 then P.strength=4;P:setFrameColor(4)break end end
end,
bgm={'battle','cruelty','distortion','far','final','hope','magicblock','new era','push','race','rockblock','secret7th','secret8th','shining terminal','storm','super7th','warped','waterfall'}, bgm={'battle','cruelty','distortion','far','final','hope','magicblock','new era','push','race','rockblock','secret7th','secret8th','shining terminal','storm','super7th','warped','waterfall'},
}, },
load=function() load=function()
PLY.newPlayer(1) PLY.newPlayer(1)
PLAYERS[1].sid=netPLY.getSID(USER.uid) PLAYERS[1].sid=netPLY.getSID(USER.uid)
local N=2
for i=2,netPLY.getCount()do for i=2,netPLY.getCount()do
PLY.newRemotePlayer(i,false,netPLY.rawgetPLY(i)) local p=netPLY.rawgetPLY(i)
if p.connected then
PLY.newRemotePlayer(N,false,p)
N=N+1
end
end end
end, end,
} }

View File

@@ -23,6 +23,7 @@ return{
garbageSpeed=.3, garbageSpeed=.3,
pushSpeed=2, pushSpeed=2,
freshLimit=15, freshLimit=15,
initSkip=true,
bg='rainbow',bgm='sugar fairy', bg='rainbow',bgm='sugar fairy',
}, },
load=function() load=function()

View File

@@ -23,6 +23,7 @@ return{
garbageSpeed=.3, garbageSpeed=.3,
pushSpeed=2, pushSpeed=2,
freshLimit=15, freshLimit=15,
initSkip=true,
bg='rainbow',bgm='rockblock', bg='rainbow',bgm='rockblock',
}, },
load=function() load=function()

View File

@@ -23,6 +23,7 @@ return{
garbageSpeed=.3, garbageSpeed=.3,
pushSpeed=2, pushSpeed=2,
freshLimit=15, freshLimit=15,
initSkip=true,
bg='rainbow',bgm='magicblock', bg='rainbow',bgm='magicblock',
}, },
load=function() load=function()

View File

@@ -23,6 +23,7 @@ return{
garbageSpeed=.3, garbageSpeed=.3,
pushSpeed=2, pushSpeed=2,
freshLimit=15, freshLimit=15,
initSkip=true,
bg='rainbow',bgm='sugar fairy', bg='rainbow',bgm='sugar fairy',
}, },
load=function() load=function()

View File

@@ -23,6 +23,7 @@ return{
garbageSpeed=.3, garbageSpeed=.3,
pushSpeed=2, pushSpeed=2,
freshLimit=15, freshLimit=15,
initSkip=true,
bg='rainbow',bgm='rockblock', bg='rainbow',bgm='rockblock',
}, },
load=function() load=function()

View File

@@ -23,6 +23,7 @@ return{
garbageSpeed=.3, garbageSpeed=.3,
pushSpeed=2, pushSpeed=2,
freshLimit=15, freshLimit=15,
initSkip=true,
bg='rainbow',bgm='magicblock', bg='rainbow',bgm='magicblock',
}, },
load=function() load=function()

View File

@@ -8,21 +8,26 @@ local NET={
connected=false, connected=false,
allow_online=false, allow_online=false,
accessToken=false, accessToken=false,
roomList={}, roomList={},--Local roomlist, updated frequently
roomInfo={ roomState={--A copy of room structure on server
-- rid=false, roomInfo={
name=false, name=false,
-- type=false, type=false,
private=false, version=false,
-- count=false, },
roomData={},
count=false,
capacity=false, capacity=false,
private=false,
start=false, start=false,
}, },
spectate=false,--If player is spectating
streamRoomID=false,
seed=false,
allReady=false, allReady=false,
connectingStream=false, connectingStream=false,
waitingStream=false, waitingStream=false,
serverGaming=false,
streamRoomID=false,
UserCount="_", UserCount="_",
PlayCount="_", PlayCount="_",
@@ -130,11 +135,11 @@ function NET.wsconn_play()
end end
function NET.wsconn_stream() function NET.wsconn_stream()
if NET.lock('wsc_stream',5)then if NET.lock('wsc_stream',5)then
NET.serverGaming=true NET.roomState.start=true
WS.connect('stream','/stream',JSON.encode{ WS.connect('stream','/stream',JSON.encode{
uid=USER.uid, uid=USER.uid,
accessToken=NET.accessToken, accessToken=NET.accessToken,
rid=NET.streamRoomID, srid=NET.streamRoomID,
}) })
TASK.new(NET.updateWS_stream) TASK.new(NET.updateWS_stream)
end end
@@ -145,7 +150,7 @@ function NET.wsclose_app()WS.close('app')end
function NET.wsclose_user()WS.close('user')end function NET.wsclose_user()WS.close('user')end
function NET.wsclose_play()WS.close('play')end function NET.wsclose_play()WS.close('play')end
function NET.wsclose_stream() function NET.wsclose_stream()
NET.serverGaming=false NET.roomState.start=false
WS.close('stream') WS.close('stream')
end end
@@ -162,6 +167,18 @@ function NET.register(username,email,password)
}) })
end end
end end
function NET.tryLogin(ifAuto)
if NET.allow_online then
if WS.status('user')=='running'then
NET.getAccessToken()
elseif not ifAuto then
SCN.go('login')
end
else
TEXT.show(text.needUpdate,640,450,60,'flicker')
SFX.play('finesseError')
end
end
function NET.pong(wsName,message) function NET.pong(wsName,message)
WS.send(wsName,type(message)=='string'and message or"",'pong') WS.send(wsName,type(message)=='string'and message or"",'pong')
end end
@@ -204,17 +221,20 @@ function NET.fetchRoom()
end end
function NET.createRoom(roomName,capacity,roomType,password) function NET.createRoom(roomName,capacity,roomType,password)
if NET.lock('enterRoom',1.26)then if NET.lock('enterRoom',1.26)then
NET.roomInfo.name=roomName NET.roomState.private=not not password
NET.roomInfo.type=roomType NET.roomState.capacity=capacity
NET.roomInfo.private=not not password
NET.roomInfo.capacity=capacity
WS.send('play',JSON.encode{ WS.send('play',JSON.encode{
action=1, action=1,
data={ data={
name=roomName,
capacity=capacity, capacity=capacity,
roomData={type=roomType},
password=password, password=password,
roomInfo={
name=roomName,
type=roomType,
version=VERSION.short,
},
roomData={_=0},
config=dumpBasicConfig(), config=dumpBasicConfig(),
} }
}) })
@@ -223,11 +243,6 @@ end
function NET.enterRoom(room,password) function NET.enterRoom(room,password)
if NET.lock('enterRoom',1.26)then if NET.lock('enterRoom',1.26)then
SFX.play('reach',.6) SFX.play('reach',.6)
NET.roomInfo.name=room.name
NET.roomInfo.type=room.type
NET.roomInfo.private=not not password
NET.roomInfo.capacity=room.capacity
NET.roomInfo.start=room.start
WS.send('play',JSON.encode{ WS.send('play',JSON.encode{
action=2, action=2,
data={ data={
@@ -254,9 +269,9 @@ end
function NET.changeConfig() function NET.changeConfig()
WS.send('play','{"action":5,"data":'..JSON.encode({config=dumpBasicConfig()})..'}') WS.send('play','{"action":5,"data":'..JSON.encode({config=dumpBasicConfig()})..'}')
end end
function NET.signal_ready(ready) function NET.signal_joinMode(ready)
if NET.lock('ready',3)and not NET.serverGaming then if NET.lock('ready',3)and not NET.roomState.start then
WS.send('play','{"action":6,"data":{"ready":'..tostring(ready)..'}}') WS.send('play','{"action":6,"data":'..JSON.encode{mode=ready}..'}')
end end
end end
function NET.signal_die() function NET.signal_die()
@@ -296,12 +311,15 @@ function NET.updateWS_app()
NET.allow_online=true NET.allow_online=true
if USER.authToken then if USER.authToken then
NET.wsconn_user_token(USER.uid,USER.authToken) NET.wsconn_user_token(USER.uid,USER.authToken)
elseif SCN.cur=='main'then
SCN.go('login')
end end
end end
if VERSION.code<res.newestCode then if VERSION.code<res.newestCode then
LOG.print(text.oldVersion:gsub("$1",res.newestName),180,'message') LOG.print(text.oldVersion:gsub("$1",res.newestName),180,'message')
end end
LOG.print(res.notice,300,'message') LOG.print(res.notice,300,'message')
NET.tryLogin(true)
elseif res.action==0 then--Get new version info elseif res.action==0 then--Get new version info
--? --?
elseif res.action==1 then--Get notice elseif res.action==1 then--Get notice
@@ -392,6 +410,7 @@ function NET.updateWS_play()
SCN.go('net_menu') SCN.go('net_menu')
NET.unlock('wsc_play') NET.unlock('wsc_play')
NET.unlock('access_and_login') NET.unlock('access_and_login')
SFX.play('connected')
elseif res.action==0 then--Fetch rooms elseif res.action==0 then--Fetch rooms
NET.roomList=res.roomList NET.roomList=res.roomList
NET.unlock('fetchRoom') NET.unlock('fetchRoom')
@@ -407,20 +426,38 @@ function NET.updateWS_play()
uid=p.uid, uid=p.uid,
username=p.username, username=p.username,
sid=p.sid, sid=p.sid,
ready=p.ready, mode=p.mode,
config=p.config, config=p.config,
} }
end end
end end
--TODO: d.roomData (json) NET.roomState.roomInfo=d.roomInfo
NET.roomState.roomData=d.roomData
NET.roomState.count=d.count
NET.roomState.capacity=d.capacity
NET.roomState.private=d.private
NET.roomState.start=d.start
NET.allReady=false
NET.connectingStream=false
NET.waitingStream=false
NET.spectate=false
NET.streamRoomID=false
loadGame('netBattle',true,true) loadGame('netBattle',true,true)
if d.srid then
NET.spectate=true
NET.streamRoomID=d.srid
NET.connectingStream=true
end
else else
--Load other players --Load other players
netPLY.add{ netPLY.add{
uid=d.uid, uid=d.uid,
username=d.username, username=d.username,
sid=d.sid, sid=d.sid,
ready=d.ready, mode=d.mode,
config=d.config, config=d.config,
} }
if SCN.socketRead then SCN.socketRead('join',d)end if SCN.socketRead then SCN.socketRead('join',d)end
@@ -442,20 +479,21 @@ function NET.updateWS_play()
if SCN.socketRead then SCN.socketRead('talk',d)end if SCN.socketRead then SCN.socketRead('talk',d)end
elseif res.action==5 then--Player change settings elseif res.action==5 then--Player change settings
netPLY.setConf(d.uid,d.config) netPLY.setConf(d.uid,d.config)
elseif res.action==6 then--One ready elseif res.action==6 then--Player change join mode
netPLY.setReady(d.uid,d.ready) netPLY.setJoinMode(d.uid,d.mode)
elseif res.action==7 then--All Ready elseif res.action==7 then--All Ready
SFX.play('reach',.6) SFX.play('reach',.6)
NET.allReady=true NET.allReady=true
elseif res.action==8 then--Set elseif res.action==8 then--Set
NET.streamRoomID=d.rid NET.streamRoomID=d.srid
NET.allReady=false NET.allReady=false
NET.connectingStream=true NET.connectingStream=true
NET.wsconn_stream() NET.wsconn_stream()
elseif res.action==9 then--Game finished elseif res.action==9 then--Game finished
NET.wsclose_stream() NET.roomState.start=false
NET.spectate=false
if SCN.socketRead then SCN.socketRead('finish',d)end if SCN.socketRead then SCN.socketRead('finish',d)end
NET.roomInfo.start=false NET.wsclose_stream()
end end
else else
WS.alert('play') WS.alert('play')
@@ -484,17 +522,38 @@ function NET.updateWS_stream()
if res.type=='Connect'then if res.type=='Connect'then
NET.unlock('wsc_stream') NET.unlock('wsc_stream')
NET.connectingStream=false NET.connectingStream=false
NET.waitingStream=true
netPLY.setConnect(USER.uid)
netPLY.freshStreamConn(res.data.connected)
elseif res.action==0 then--Game start elseif res.action==0 then--Game start
NET.waitingStream=false NET.waitingStream=false
if SCN.socketRead then SCN.socketRead('go',d)end SCN.socketRead('go')
NET.roomInfo.start=true
elseif res.action==1 then--Game finished elseif res.action==1 then--Game finished
--? --?
elseif res.action==2 then--Player join elseif res.action==2 then--Player join
netPLY.setConnect(d.uid) if res.type=='Self'then
NET.seed=d.seed
NET.spectate=d.spectate
netPLY.setConnect(d.uid)
for _,p in next,d.connected do
if not p.spectate then
netPLY.setConnect(p.uid)
end
end
if d.spectate then
if d.start then
SCN.socketRead('go')
for _,v in next,d.history or{}do
SCN.socketRead('stream',v)
end
end
else
NET.waitingStream=true
end
else
if d.spectate then
netPLY.setJoinMode(d.uid,2)
else
netPLY.setConnect(d.uid)
end
end
elseif res.action==3 then--Player leave elseif res.action==3 then--Player leave
--? --?
elseif res.action==4 then--Player died elseif res.action==4 then--Player died

View File

@@ -87,6 +87,7 @@ end
function netPLY.clear()for _=1,netPLY.getCount()do rem(PLY)end end function netPLY.clear()for _=1,netPLY.getCount()do rem(PLY)end end
function netPLY.add(p) function netPLY.add(p)
p.mode=0
p.connected=false p.connected=false
ins(PLY,p.uid==USER.uid and 1 or #PLY+1,p) ins(PLY,p.uid==USER.uid and 1 or #PLY+1,p)
local a=rnd()*6.2832 local a=rnd()*6.2832
@@ -99,23 +100,23 @@ end
function netPLY.getCount()return #PLY end function netPLY.getCount()return #PLY end
function netPLY.rawgetPLY(i)return PLY[i]end function netPLY.rawgetPLY(i)return PLY[i]end
function netPLY.getUsername(uid)return getPLY(uid).username end
function netPLY.getSID(uid)return getPLY(uid).sid end function netPLY.getSID(uid)return getPLY(uid).sid end
function netPLY.getSelfReady()return PLY[1].ready end function netPLY.getSelfJoinMode()return PLY[1].mode end
function netPLY.getSelfReady()return PLY[1].mode>0 end
function netPLY.setPlayerObj(ply,p)ply.p=p end function netPLY.setPlayerObj(ply,p)ply.p=p end
function netPLY.setConf(uid,config)getPLY(uid).config=config end function netPLY.setConf(uid,config)getPLY(uid).config=config end
function netPLY.setReady(uid,ready) function netPLY.setJoinMode(uid,ready)
for i,p in next,PLY do for i,p in next,PLY do
if p.uid==uid then if p.uid==uid then
if p.ready~=ready then if p.mode~=ready then
p.ready=ready p.mode=ready
if not ready then NET.allReady=false end if ready==0 then NET.allReady=false end
SFX.play('spin_0',.6) SFX.play('spin_0',.6)
if i==1 then if i==1 then
NET.unlock('ready') NET.unlock('ready')
elseif not PLY[1].ready then elseif PLY[1].mode==0 then
for j=2,#PLY do for j=2,#PLY do
if not PLY[j].ready then if PLY[j].mode==0 then
return return
end end
end end
@@ -126,22 +127,10 @@ function netPLY.setReady(uid,ready)
end end
end end
end end
function netPLY.setConnect(uid) function netPLY.setConnect(uid)getPLY(uid).connected=true end
for _,p in next,PLY do
if p.uid==uid then
p.connected=true
return
end
end
end
function netPLY.freshStreamConn(list)
for _,p in next,list do
getPLY(p.uid).connected=true
end
end
function netPLY.resetState() function netPLY.resetState()
for i=1,#PLY do for i=1,#PLY do
PLY[i].ready=false PLY[i].mode=0
PLY[i].connected=false PLY[i].connected=false
end end
end end
@@ -179,7 +168,11 @@ function netPLY.draw()
local p=PLY[i] local p=PLY[i]
gc.translate(p.x,p.y) gc.translate(p.x,p.y)
--Rectangle --Rectangle
gc.setColor(COLOR[p.connected and"N"or p.ready and'A'or'Z']) gc.setColor(COLOR[
p.mode==0 and'Z'or
p.mode==1 and(p.connected and"N"or"G")or
p.mode==2 and(p.connected and"Y"or"F")
])
gc.setLineWidth(2) gc.setLineWidth(2)
gc.rectangle('line',0,0,p.w,p.h) gc.rectangle('line',0,0,p.w,p.h)
@@ -199,8 +192,8 @@ function netPLY.draw()
gc.print("#"..p.uid,50,-5) gc.print("#"..p.uid,50,-5)
gc.print(p.username,210,-5) gc.print(p.username,210,-5)
else else
setFont(159) setFont(15)
gc.print("#"..p.uid,p.h,-2) gc.print("#"..p.uid,46,-1)
setFont(30) setFont(30)
gc.print(p.username,p.h,8) gc.print(p.username,p.h,8)
end end

View File

@@ -111,6 +111,11 @@ return{
font=65, font=65,
color=C.rainbow_dark, color=C.rainbow_dark,
}, },
{
name="亮君吧",
font=65,
color=C.rainbow_dark,
},
{ {
name="八零哥", name="八零哥",

View File

@@ -1,6 +1,6 @@
local gc=love.graphics local gc=love.graphics
local gc_push,gc_pop,gc_clear,gc_origin=gc.push,gc.pop,gc.clear,gc.origin local gc_push,gc_pop,gc_clear,gc_origin=gc.push,gc.pop,gc.clear,gc.origin
local gc_translate,gc_scale,gc_rotate=gc.translate,gc.scale,gc.rotate local gc_translate,gc_scale,gc_rotate,gc_shear=gc.translate,gc.scale,gc.rotate,gc.shear
local gc_setCanvas,gc_setShader=gc.setCanvas,gc.setShader local gc_setCanvas,gc_setShader=gc.setCanvas,gc.setShader
local gc_draw,gc_line,gc_rectangle=gc.draw,gc.line,gc.rectangle local gc_draw,gc_line,gc_rectangle=gc.draw,gc.line,gc.rectangle
local gc_print,gc_printf=gc.print,gc.printf local gc_print,gc_printf=gc.print,gc.printf
@@ -9,7 +9,7 @@ local gc_stencil,gc_setStencilTest=gc.stencil,gc.setStencilTest
local int,ceil,rnd=math.floor,math.ceil,math.random local int,ceil,rnd=math.floor,math.ceil,math.random
local max,min,sin,modf=math.max,math.min,math.sin,math.modf local max,min,sin,modf=math.max,math.min,math.sin,math.modf
local setFont,mDraw,mStr,mText=setFont,mDraw,mStr,mText local setFont,mDraw,mStr=setFont,mDraw,mStr
local SKIN,TEXTURE,IMG=SKIN,TEXTURE,IMG local SKIN,TEXTURE,IMG=SKIN,TEXTURE,IMG
local TEXT,COLOR,GAME,TIME=TEXT,COLOR,GAME,TIME local TEXT,COLOR,GAME,TIME=TEXT,COLOR,GAME,TIME
local shader_alpha,shader_lighter=SHADER.alpha,SHADER.lighter local shader_alpha,shader_lighter=SHADER.alpha,SHADER.lighter
@@ -50,6 +50,12 @@ local spinCenterImg=DOGC{9,9,
{'setCL',1,1,1}, {'setCL',1,1,1},
{'fRect',3,3,3,3}, {'fRect',3,3,3,3},
} }
local playerBoarders=DOGC{334,614,
{'setLW',2},
{'dRect',16,1,302,612},
{'dRect',318,9,15,604},
{'dRect',1,9,15,604},
}
local gridLines do local gridLines do
local L={300,640,{'setLW',2}} local L={300,640,{'setLW',2}}
for x=1,9 do table.insert(L,{'line',30*x,0,30*x,640})end for x=1,9 do table.insert(L,{'line',30*x,0,30*x,640})end
@@ -249,13 +255,6 @@ local function drawNextPreview(P,B)
end end
end end end end
end end
local function drawBoarders(P)
gc_setLineWidth(2)
gc_setColor(P.frameColor)
gc_rectangle('line',-1,-11,302,612)--Bis Boarder
gc_rectangle('line',301,-3,15,604)
gc_rectangle('line',-16,-3,15,604)--B2b bar boarder
end
local function drawBuffer(P) local function drawBuffer(P)
local h=0 local h=0
for i=1,#P.atkBuffer do for i=1,#P.atkBuffer do
@@ -294,9 +293,15 @@ local function drawBuffer(P)
gc_push('transform') gc_push('transform')
gc_translate(300,max(0,600-30*sum)) gc_translate(300,max(0,600-30*sum))
gc_scale(min(.2+sum/50,1)) gc_scale(min(.2+sum/50,1))
setFont(100)
gc_setColor(1,.2+min(sum*.02,.8)*(.5+.5*sin(TIME()*min(sum,32))),.2,min(sum/30,.8)) gc_setColor(1,.2+min(sum*.02,.8)*(.5+.5*sin(TIME()*min(sum,32))),.2,min(sum/30,.8))
gc_printf(int(P.atkBufferSum1),-300,-20,292,'right') setFont(100)
if sum>20 then
local d=P.atkBufferSum-sum
if d>.5 then
gc_translate(d^.5*(rnd()-.5)*15,d^.5*(rnd()-.5)*15)
end
end
gc_printf(int(sum),-300,-20,292,'right')
gc_pop() gc_pop()
end end
end end
@@ -312,14 +317,14 @@ local function drawB2Bbar(P)
gc_rectangle('fill',-15,b<40 and 568.5 or 118.5,13,3) gc_rectangle('fill',-15,b<40 and 568.5 or 118.5,13,3)
end end
end end
local function drawLDI(P)--Lock Delay Indicator local function drawLDI(P,ENV)--Lock Delay Indicator
if P.gameEnv.easyFresh then if ENV.easyFresh then
gc_setColor(1,1,1) gc_setColor(1,1,1)
else else
gc_setColor(1,.26,.26) gc_setColor(1,.26,.26)
end end
if P.lockDelay>=0 then if P.lockDelay>=0 then
gc_rectangle('fill',0,602,300*P.lockDelay/P.gameEnv.lock,6)--Lock delay indicator gc_rectangle('fill',0,602,300*P.lockDelay/ENV.lock,6)--Lock delay indicator
end end
if P.freshTime>0 then if P.freshTime>0 then
LDmarks:setDrawRange(1,min(P.freshTime,15)) LDmarks:setDrawRange(1,min(P.freshTime,15))
@@ -333,11 +338,10 @@ local function drawHold(P)
local holdQueue=P.holdQueue local holdQueue=P.holdQueue
local N=ENV.holdCount*72 local N=ENV.holdCount*72
gc_push('transform') gc_push('transform')
gc_translate(-140,36) gc_translate(-140,20)
gc_setColor(0,0,0,.4)gc_rectangle('fill',0,0,124,N+8) gc_setColor(0,0,0,.4)gc_rectangle('fill',0,0,124,N+8)
gc_setColor(1,1,1)gc_rectangle('line',0,0,124,N+8) gc_setColor(1,1,1)gc_rectangle('line',0,0,124,N+8)
if P.holdTime==0 then gc_setColor(.6,.4,.4)end if P.holdTime==0 then gc_setColor(.6,.4,.4)end
mText(drawableText.hold,62,-51)
gc_setColor(1,1,1) gc_setColor(1,1,1)
if #holdQueue<ENV.holdCount and P.nextQueue[1]then if #holdQueue<ENV.holdCount and P.nextQueue[1]then
@@ -441,13 +445,25 @@ local function drawMission(P)
end end
end end
end end
local function drawStartCounter(count) local function drawStartCounter(P)
gc_setColor(1,1,1) local count=179-P.frameRun
gc_push('transform') gc_push('transform')
gc_translate(305,220) gc_translate(300,300)
if count%60>45 then gc_scale(1+(count%60-45)^2*.01,1)end local num=int(count/60+1)
setFont(95) local d=count%60-45
mStr(int(count/60+1),0,0) if num==3 then
gc_setColor(.7,.9,1)
if d>0 then gc_scale(1+d^2*.01,1)end
elseif num==2 then
gc_setColor(1,.95,.7)
if d>0 then gc_shear(-(d/15)^2,0)end
elseif num==1 then
gc_setColor(1,.8,.8)
if d>0 then gc_rotate(d^2*.00355)end
end
setFont(100)
mStr(num,0,-70)
--P.gameEnv.initSkip
gc_pop() gc_pop()
end end
@@ -455,11 +471,10 @@ local draw={}
function draw.drawNext_norm(P) function draw.drawNext_norm(P)
local ENV=P.gameEnv local ENV=P.gameEnv
local texture=SKIN.curText local texture=SKIN.curText
gc_translate(316,36) gc_translate(316,20)
local N=ENV.nextCount*72 local N=ENV.nextCount*72
gc_setColor(0,0,0,.4)gc_rectangle('fill',0,0,124,N+8) gc_setColor(0,0,0,.4)gc_rectangle('fill',0,0,124,N+8)
gc_setColor(1,1,1)gc_rectangle('line',0,0,124,N+8) gc_setColor(1,1,1)gc_rectangle('line',0,0,124,N+8)
mText(drawableText.next,62,-51)
N=1 N=1
gc_push('transform') gc_push('transform')
gc_translate(62,40) gc_translate(62,40)
@@ -484,16 +499,15 @@ function draw.drawNext_norm(P)
gc_rectangle('fill',2,72*i+3,120,2) gc_rectangle('fill',2,72*i+3,120,2)
end end
end end
gc_translate(-316,-36) gc_translate(-316,-20)
end end
function draw.drawNext_hidden(P) function draw.drawNext_hidden(P)
local ENV=P.gameEnv local ENV=P.gameEnv
local texture=SKIN.curText local texture=SKIN.curText
gc_translate(316,36) gc_translate(316,20)
local N=ENV.nextCount*72 local N=ENV.nextCount*72
gc_setColor(.5,0,0,.4)gc_rectangle('fill',0,0,124,N+8) gc_setColor(.5,0,0,.4)gc_rectangle('fill',0,0,124,N+8)
gc_setColor(1,1,1)gc_rectangle('line',0,0,124,N+8) gc_setColor(1,1,1)gc_rectangle('line',0,0,124,N+8)
mText(drawableText.next,62,-51)
N=min(ENV.nextStartPos,P.pieceCount+1) N=min(ENV.nextStartPos,P.pieceCount+1)
gc_push('transform') gc_push('transform')
gc_translate(62,40) gc_translate(62,40)
@@ -519,7 +533,7 @@ function draw.drawNext_hidden(P)
gc_rectangle('fill',2,72*i+3,120,2) gc_rectangle('fill',2,72*i+3,120,2)
end end
end end
gc_translate(-316,-36) gc_translate(-316,-20)
end end
draw.applyFieldOffset=applyFieldOffset draw.applyFieldOffset=applyFieldOffset
@@ -636,12 +650,16 @@ function draw.norm(P)
gc_pop() gc_pop()
gc_setStencilTest() gc_setStencilTest()
drawBoarders(P) gc_setLineWidth(2)
P:drawNext()
drawHold(P)
drawBuffer(P) drawBuffer(P)
drawB2Bbar(P) drawB2Bbar(P)
drawLDI(P) drawLDI(P,ENV)
drawHold(P)
P:drawNext() --Draw boarders
gc_setColor(P.frameColor)
gc.draw(playerBoarders,-17,-12)
--Draw target selecting pad --Draw target selecting pad
if GAME.modeEnv.royaleMode then if GAME.modeEnv.royaleMode then
@@ -656,6 +674,8 @@ function draw.norm(P)
gc_printf(text.atkModeName[i],RCPB[2*i-1]-4,RCPB[2*i]+4,200,"center",nil,.5) gc_printf(text.atkModeName[i],RCPB[2*i-1]-4,RCPB[2*i]+4,200,"center",nil,.5)
end end
end end
--Board cover
if ENV.hideBoard then if ENV.hideBoard then
gc_stencil(hideBoardStencil[ENV.hideBoard],'replace',1) gc_stencil(hideBoardStencil[ENV.hideBoard],'replace',1)
gc_setStencilTest('equal',1) gc_setStencilTest('equal',1)
@@ -666,13 +686,28 @@ function draw.norm(P)
end end
gc_setStencilTest() gc_setStencilTest()
end end
--Spike
local sp,spt=P.spike,P.spikeTime
if ENV.showSpike and spt>0 and sp>=10 then
local rg=10/sp
gc_setColor(rg,rg,1,min(spt/30,.8))
local x,y=150,100
if spt>85 then
local d=2*(spt-85)*min(sp/50,1)
x,y=x+(rnd()-.5)*d,y+(rnd()-.5)*d
end
mDraw(P.spikeText,x,y,nil,min(.3+(sp/26)*.4+spt/100*.3,1))
end
--Bonus texts --Bonus texts
TEXT.draw(P.bonus) TEXT.draw(P.bonus)
--Display Ys --Display Ys
-- gc_setLineWidth(6) -- gc_setLineWidth(6)
-- if P.curY then gc_setColor(COLOR.R)gc_line(0,611-P.curY*30,300,610-P.curY*30)end -- if P.curY then gc_setColor(COLOR.R) gc_line(0,611-P.curY*30,300,610-P.curY*30)end
-- if P.ghoY then gc_setColor(COLOR.G)gc_line(0,615-P.ghoY*30,300,615-P.ghoY*30)end -- if P.ghoY then gc_setColor(COLOR.G) gc_line(0,615-P.ghoY*30,300,615-P.ghoY*30)end
-- if P.minY then gc_setColor(COLOR.B)gc_line(0,619-P.minY*30,300,620-P.minY*30)end -- if P.minY then gc_setColor(COLOR.B) gc_line(0,619-P.minY*30,300,620-P.minY*30)end
-- gc_line(0,600-P.garbageBeneath*30,300,600-P.garbageBeneath*30) -- gc_line(0,600-P.garbageBeneath*30,300,600-P.garbageBeneath*30)
gc_pop() gc_pop()
@@ -705,7 +740,7 @@ function draw.norm(P)
if P.life>0 then drawLife(P.life)end if P.life>0 then drawLife(P.life)end
drawMission(P) drawMission(P)
if P.frameRun<180 then drawStartCounter(179-P.frameRun)end if P.frameRun<180 then drawStartCounter(P)end
gc_pop() gc_pop()
end end
function draw.small(P) function draw.small(P)

View File

@@ -22,6 +22,8 @@ return{
bufferWarn=false, bufferWarn=false,
highCam=false, highCam=false,
nextPos=false, nextPos=false,
showSpike=false,
hideBoard=false, hideBoard=false,
flipBoard=false, flipBoard=false,

View File

@@ -79,6 +79,7 @@ local function newEmptyPlayer(id,mini)
--Inherit functions of Player class --Inherit functions of Player class
for k,v in next,Player do P[k]=v end for k,v in next,Player do P[k]=v end
--Set key/timer event
if P.id==1 and GAME.recording then if P.id==1 and GAME.recording then
P.pressKey=pressKey_Rec P.pressKey=pressKey_Rec
P.releaseKey=releaseKey_Rec P.releaseKey=releaseKey_Rec
@@ -88,6 +89,7 @@ local function newEmptyPlayer(id,mini)
end end
P.update=ply_update.alive P.update=ply_update.alive
--Field position
P.fieldOff={--Shake FX P.fieldOff={--Shake FX
x=0,y=0, x=0,y=0,
vx=0,vy=0, vx=0,vy=0,
@@ -101,8 +103,8 @@ local function newEmptyPlayer(id,mini)
-- P.centerX,P.centerY=... -- P.centerX,P.centerY=...
-- P.absFieldX,P.absFieldY=... -- P.absFieldX,P.absFieldY=...
--If draw in small mode --Minimode
P.mini=mini P.miniMode=mini
if mini then if mini then
P.canvas=love.graphics.newCanvas(60,120) P.canvas=love.graphics.newCanvas(60,120)
P.frameWait=rnd(26,62) P.frameWait=rnd(26,62)
@@ -111,60 +113,87 @@ local function newEmptyPlayer(id,mini)
P.draw=ply_draw.norm P.draw=ply_draw.norm
end end
--States
P.type='none'
P.sound=false
P.alive=true
P.control=false
P.timing=false
P.result=false--String: 'finish'|'win'|'lose'
P.stat=getNewStatTable()
P.modeData=setmetatable({},modeDataMeta)--Data use by mode
P.keyPressing={}for i=1,12 do P.keyPressing[i]=false end
P.clearingRow,P.clearedRow={},{}--Clearing animation height,cleared row mark
P.dropFX,P.moveFX,P.lockFX,P.clearFX={},{},{},{}
P.tasks={}
P.bonus={}--Texts
--Times
P.frameRun=GAME.frameStart--Frame run, mainly for replay
P.endCounter=0--Used after gameover
P.keyTime={}for i=1,10 do P.keyTime[i]=-1e99 end P.keySpeed=0
P.dropTime={}for i=1,10 do P.dropTime[i]=-1e99 end P.dropSpeed=0
--Randomizers
P.seqRND=love.math.newRandomGenerator(GAME.seed) P.seqRND=love.math.newRandomGenerator(GAME.seed)
P.atkRND=love.math.newRandomGenerator(GAME.seed) P.atkRND=love.math.newRandomGenerator(GAME.seed)
P.holeRND=love.math.newRandomGenerator(GAME.seed) P.holeRND=love.math.newRandomGenerator(GAME.seed)
P.aiRND=love.math.newRandomGenerator(GAME.seed) P.aiRND=love.math.newRandomGenerator(GAME.seed)
P.frameRun=GAME.frameStart --Field-related
P.alive=true
P.control=false
P.timing=false
P.stat=getNewStatTable()
P.modeData=setmetatable({},modeDataMeta)--Data use by mode
P.keyTime={}P.keySpeed=0
P.dropTime={}P.dropSpeed=0
for i=1,10 do P.keyTime[i]=-1e99 end
for i=1,10 do P.dropTime[i]=-1e99 end
P.field,P.visTime={},{} P.field,P.visTime={},{}
P.atkBuffer={} P.keepVisible=true
P.atkBufferSum=0 P.showTime=false
P.atkBufferSum1=0 P.garbageBeneath=0
P.fieldBeneath=0
P.fieldUp=0
--Royale-related --Attack-related
P.atkBuffer={}
P.atkBufferSum,P.atkBufferSum1=0,0
P.spike,P.spikeTime=0,0
P.spikeText=love.graphics.newText(getFont(100))
--Attacker-related
P.badge,P.strength=0,0 P.badge,P.strength=0,0
P.atkMode,P.swappingAtkMode=1,20 P.atkMode,P.swappingAtkMode=1,20
P.atker,P.atking,P.lastRecv={} P.atker,P.atking,P.lastRecv={}
--Network-related --User-related
P.username="" P.username=""
P.uid=false P.uid=false
P.sid=false P.sid=false
P.dropDelay,P.lockDelay=0,0 --Block states
P.showTime=false
P.keepVisible=true
--[[ --[[
P.cur={ P.curX,P.curY,P.ghoY,P.minY=0,0,0,0--x,y,ghostY
id=shapeID, P.cur={
bk=matrix[2], id=shapeID,
sc=table[2], bk=matrix[2],
dir=direction, sc=table[2],
name=nameID dir=direction,
color=colorID, name=nameID
} color=colorID,
}
P.newNext=false--Warped coroutine to get new next, loaded in applyGameEnv()
]] ]]
-- P.curX,P.curY,P.ghoY,P.minY=0,0,0,0--x,y,ghostY P.movDir,P.moving,P.downing=0,0,0--Last move key,DAS charging,downDAS charging
P.holdQueue={} P.dropDelay,P.lockDelay=0,0
P.holdTime=0 P.waiting,P.falling=-1,-1
P.nextQueue={}
P.freshTime=0 P.freshTime=0
P.spinLast=false P.spinLast=false
P.spinSeq=0--For Ospin, each digit mean a spin
P.ctrlCount=0--Key press time, for finesse check
--Game states
P.combo=0
P.b2b,P.b2b1=0,0--B2B point & Displayed B2B point
P.score1=0--Displayed score
P.pieceCount=0--Count pieces from next, for drawing bagline
P.finesseCombo,P.finesseComboTime=0,0
P.nextQueue={}
P.holdQueue={}
P.holdTime=0
P.lastPiece={ P.lastPiece={
id=0,name=0,--block id/name id=0,name=0,--block id/name
@@ -179,34 +208,6 @@ local function newEmptyPlayer(id,mini)
pc=false,hpc=false,--if pc/hpc pc=false,hpc=false,--if pc/hpc
special=false,--if special clear (spin, >=4, pc) special=false,--if special clear (spin, >=4, pc)
} }
P.spinSeq=0--For Ospin, each digit mean a spin
P.ctrlCount=0--Key press time, for finesse check
P.pieceCount=0--Count pieces from next, for drawing bagline
P.type='none'
P.sound=false
-- P.newNext=false--Warped coroutine to get new next, loaded in applyGameEnv()
P.keyPressing={}for i=1,12 do P.keyPressing[i]=false end
P.movDir,P.moving,P.downing=0,0,0--Last move key,DAS charging,downDAS charging
P.waiting,P.falling=-1,-1
P.clearingRow,P.clearedRow={},{}--Clearing animation height,cleared row mark
P.combo,P.b2b=0,0
P.finesseCombo=0
P.garbageBeneath=0
P.fieldBeneath=0
P.fieldUp=0
P.score1,P.b2b1=0,0
P.finesseComboTime=0
P.dropFX,P.moveFX,P.lockFX,P.clearFX={},{},{},{}
P.tasks={}--Tasks
P.bonus={}--Text objects
P.endCounter=0--Used after gameover
P.result=false--String: 'finish'|'win'|'lose'
return P return P
end end
local function loadGameEnv(P)--Load gameEnv local function loadGameEnv(P)--Load gameEnv
@@ -321,7 +322,7 @@ local function applyGameEnv(P)--Finish gameEnv processing
P.newNext=coroutine.wrap(seqGenerators(P)) P.newNext=coroutine.wrap(seqGenerators(P))
P.newNext(P,P.gameEnv.seqData) P.newNext(P,P.gameEnv.seqData)
if P.mini then if P.miniMode then
ENV.lockFX=false ENV.lockFX=false
ENV.dropFX=false ENV.dropFX=false
ENV.moveFX=false ENV.moveFX=false

View File

@@ -105,7 +105,7 @@ function Player:createClearingFX(y,spd)
end end
function Player:createBeam(R,send,power,color) function Player:createBeam(R,send,power,color)
local x1,y1,x2,y2 local x1,y1,x2,y2
if self.mini then x1,y1=self.centerX,self.centerY if self.miniMode then x1,y1=self.centerX,self.centerY
else x1,y1=self.x+(30*(self.curX+self.cur.sc[2])-30+15+150)*self.size,self.y+(600-30*(self.curY+self.cur.sc[1])+15)*self.size else x1,y1=self.x+(30*(self.curX+self.cur.sc[2])-30+15+150)*self.size,self.y+(600-30*(self.curY+self.cur.sc[1])+15)*self.size
end end
if R.small then x2,y2=R.centerX,R.centerY if R.small then x2,y2=R.centerX,R.centerY
@@ -136,7 +136,7 @@ end
function Player:setPosition(x,y,size) function Player:setPosition(x,y,size)
size=size or 1 size=size or 1
self.x,self.y,self.size=x,y,size self.x,self.y,self.size=x,y,size
if self.mini or self.demo then if self.miniMode or self.demo then
self.fieldX,self.fieldY=x,y self.fieldX,self.fieldY=x,y
self.centerX,self.centerY=x+300*size,y+600*size self.centerX,self.centerY=x+300*size,y+600*size
else else
@@ -1380,6 +1380,13 @@ do--Player.drop(self)--Place piece
self.combo=cmb self.combo=cmb
--Spike
if atk>0 then
self.spike=self.spikeTime==0 and atk or self.spike+atk
self.spikeTime=min(self.spikeTime+atk*20,100)
self.spikeText:set(self.spike)
end
--DropSpeed bonus --DropSpeed bonus
if self._20G then if self._20G then
cscore=cscore*2 cscore=cscore*2
@@ -1727,7 +1734,7 @@ function Player:lose(force)
for i=A.strength+1,4 do for i=A.strength+1,4 do
if A.badge>=ROYALEDATA.powerUp[i]then if A.badge>=ROYALEDATA.powerUp[i]then
A.strength=i A.strength=i
A:setFrameColor(A.strength) A:setFrameColor(i)
end end
end end
self.lastRecv=A self.lastRecv=A
@@ -1757,7 +1764,7 @@ function Player:lose(force)
end end
gameOver() gameOver()
self:newTask(#PLAYERS>1 and tick_lose or tick_finish) self:newTask(#PLAYERS>1 and tick_lose or tick_finish)
if GAME.net then if GAME.net and not NET.spectate then
NET.signal_die() NET.signal_die()
else else
TASK.new(tick_autoPause) TASK.new(tick_autoPause)

View File

@@ -3,7 +3,7 @@ local int,abs,rnd=math.floor,math.abs,math.random
local rem=table.remove local rem=table.remove
local assert,resume,status=assert,coroutine.resume,coroutine.status local assert,resume,status=assert,coroutine.resume,coroutine.status
local TEXT,GAME=TEXT,GAME local TEXT,GAME,CC=TEXT,GAME,CC
local PLY_ALIVE=PLY_ALIVE local PLY_ALIVE=PLY_ALIVE
local function update_misc(P,dt) local function update_misc(P,dt)
@@ -12,6 +12,9 @@ local function update_misc(P,dt)
P.finesseComboTime=P.finesseComboTime-1 P.finesseComboTime=P.finesseComboTime-1
end end
--Update spike counter
if P.spikeTime>0 then P.spikeTime=P.spikeTime-1 end
--Update atkBuffer alert --Update atkBuffer alert
local t=P.atkBufferSum1 local t=P.atkBufferSum1
if t<P.atkBufferSum then if t<P.atkBufferSum then
@@ -402,14 +405,15 @@ function update.dead(P,dt)
end end
function update.remote_alive(P,dt) function update.remote_alive(P,dt)
local frameRate=(P.stream[#P.stream-1]or 0)-P.frameRun local frameRate=(P.stream[#P.stream-1]or 0)-P.frameRun
frameRate=frameRate<20 and 1 or frameRate=
frameRate<30 and rnd(2)or frameRate<20 and 1 or
frameRate<60 and 2 or frameRate<30 and rnd(2)or
frameRate<90 and 3 or frameRate<60 and 2 or
frameRate<120 and 5 or frameRate<90 and 3 or
frameRate<150 and 7 or frameRate<120 and 5 or
frameRate<180 and 10 or frameRate<150 and 7 or
20 frameRate<180 and 10 or
20
for _=1,frameRate do for _=1,frameRate do
local eventTime=P.stream[P.streamProgress] local eventTime=P.stream[P.streamProgress]
if eventTime then--Normal state, event forward if eventTime then--Normal state, event forward

View File

@@ -677,8 +677,7 @@ userG.the_box=first_box
local scene={} local scene={}
function scene.sceneInit() function scene.sceneInit()
TASK.new(function()YIELD()WIDGET.sel=inputBox end) TASK.new(function()WIDGET.focus(inputBox)end)
enableTextInput()
BG.set('none') BG.set('none')
end end
@@ -688,7 +687,7 @@ end
function scene.keyDown(k) function scene.keyDown(k)
if k=="return"then if k=="return"then
local input=inputBox:getText() local input=STRING.trim(inputBox:getText())
if input==""then return end if input==""then return end
--Write History --Write History
@@ -700,7 +699,6 @@ function scene.keyDown(k)
log"" log""
--Execute --Execute
input=input:sub((input:find("%S")))
if input:byte()==35 then if input:byte()==35 then
--Execute lua code --Execute lua code
log{C.lC,"> "..input} log{C.lC,"> "..input}
@@ -780,13 +778,13 @@ function scene.keyDown(k)
elseif combKey[k]and kb.isDown("lctrl","rctrl")then elseif combKey[k]and kb.isDown("lctrl","rctrl")then
combKey[k]() combKey[k]()
elseif k=="escape"then elseif k=="escape"then
if WIDGET.sel~=inputBox then if not WIDGET.isFocus(inputBox)then
WIDGET.sel=inputBox WIDGET.focus(inputBox)
else else
SCN.back() SCN.back()
end end
else else
if WIDGET.sel~=inputBox then WIDGET.sel=inputBox end if not WIDGET.isFocus(inputBox)then WIDGET.focus(inputBox)end
WIDGET.keyPressed(k) WIDGET.keyPressed(k)
end end
end end

View File

@@ -229,7 +229,6 @@ function scene.keyDown(key)
if DATA.pasteBoard(str,page)then if DATA.pasteBoard(str,page)then
LOG.print(text.importSuccess,'message') LOG.print(text.importSuccess,'message')
else else
print(text.dataCorrupted)
LOG.print(text.dataCorrupted,'error') LOG.print(text.dataCorrupted,'error')
end end
elseif key=="pageup"then elseif key=="pageup"then

View File

@@ -68,8 +68,7 @@ function scene.sceneInit()
scrollPos=0 scrollPos=0
lastSearch=false lastSearch=false
TASK.new(function()YIELD()WIDGET.sel=inputBox end) TASK.new(function()YIELD()WIDGET.focus(inputBox)end)
enableTextInput()
BG.set('rainbow') BG.set('rainbow')
end end

View File

@@ -197,8 +197,8 @@ local loadingThread=coroutine.wrap(function()
upFloor() upFloor()
end end
if progress==25 then if progress==25 then
SFX.play("emit",.6) SFX.play('emit',.6)
SFX.play("enter",.8) SFX.play('enter',.8)
SFX.play('welcome_sfx') SFX.play('welcome_sfx')
VOC.play('welcome_voc') VOC.play('welcome_voc')
THEME.fresh() THEME.fresh()

View File

@@ -29,7 +29,6 @@ function scene.sceneInit()
emailBox:setText(data[1]) emailBox:setText(data[1])
passwordBox:setText(data[2]) passwordBox:setText(data[2])
end end
enableTextInput()
end end
scene.widgetList={ scene.widgetList={

View File

@@ -46,10 +46,10 @@ function scene.mouseDown(x,y)
end end
scene.touchDown=scene.mouseDown scene.touchDown=scene.mouseDown
local function testButton(n) local function testButton(n)
if WIDGET.sel==scene.widgetList[n]then if WIDGET.isFocus(scene.widgetList[n])then
return true return true
else else
WIDGET.sel=scene.widgetList[n] WIDGET.focus(scene.widgetList[n])
end end
end end
function scene.keyDown(key) function scene.keyDown(key)
@@ -64,21 +64,11 @@ function scene.keyDown(key)
elseif key=="a"then elseif key=="a"then
if testButton(3)then if testButton(3)then
if NET.connected then if NET.connected then
if NET.allow_online then NET.tryLogin(false)
if WS.status('user')=='running'then
NET.getAccessToken()
else
SCN.go('login')
end
else
TEXT.show(text.needUpdate,640,450,60,'flicker')
SFX.play('finesseError')
end
else else
TEXT.show(text.noInternet,640,450,60,'flicker')
NET.wsconn_app() NET.wsconn_app()
LOG.print(text.wsConnecting,'message') LOG.print(text.wsConnecting,'message')
SFX.play('finesseError') SFX.play('connect')
end end
end end
elseif key=="z"then elseif key=="z"then
@@ -131,7 +121,7 @@ function scene.update(dt)
end end
local L=scene.widgetList local L=scene.widgetList
for i=1,8 do for i=1,8 do
L[i].x=L[i].x*.9+(widgetX0[i]-400+(WIDGET.sel==L[i]and(i<5 and 100 or -100)or 0))*.1 L[i].x=L[i].x*.9+(widgetX0[i]-400+(WIDGET.isFocus(L[i])and(i<5 and 100 or -100)or 0))*.1
end end
end end

View File

@@ -21,7 +21,7 @@ local scene={}
function scene.sceneInit(org) function scene.sceneInit(org)
BG.set() BG.set()
destroyPlayers() destroyPlayers()
mapCam.zoomK=org=="main"and 5 or 1 mapCam.zoomK=org=='main'and 5 or 1
end end
local function getK() local function getK()

View File

@@ -1,10 +1,15 @@
local gc,tc,kb=love.graphics,love.touch,love.keyboard local gc,kb,tc=love.graphics,love.keyboard,love.touch
local gc_setColor,gc_print=gc.setColor,gc.print
local setFont,mStr=setFont,mStr
local ins=table.insert local ins=table.insert
local SCR,VK,NET,netPLY=SCR,VK,NET,netPLY local SCR,VK,NET,netPLY=SCR,VK,NET,netPLY
local PLAYERS,GAME=PLAYERS,GAME local PLAYERS,GAME=PLAYERS,GAME
local textBox=WIDGET.newTextBox{name="texts",x=340,y=80,w=600,h=560,hide=false} local textBox=WIDGET.newTextBox{name="texts",x=340,y=80,w=600,h=560}
local inputBox=WIDGET.newInputBox{name="input",x=340,y=660,w=600,h=50,hide=false} local inputBox=WIDGET.newInputBox{name="input",x=340,y=660,w=600,h=50}
local playing local playing
local lastUpstreamTime local lastUpstreamTime
@@ -13,6 +18,34 @@ local lastBackTime=0
local noTouch,noKey=false,false local noTouch,noKey=false,false
local touchMoveLastFrame=false local touchMoveLastFrame=false
local function _setReady()NET.signal_joinMode(1)end
local function _setSpectate()NET.signal_joinMode(2)end
local function _setCancel()NET.signal_joinMode(0)end
local function _gotoSetting()
if not(netPLY.getSelfReady()or NET.getlock('ready'))then
SCN.go('setting_game')
end
end
local function _quit()
if TIME()-lastBackTime<1 then
NET.signal_quit()
else
lastBackTime=TIME()
LOG.print(text.sureQuit,'warn')
end
end
local function _switchChat()
if inputBox.hide then
textBox.hide=false
inputBox.hide=false
WIDGET.focus(inputBox)
else
textBox.hide=true
inputBox.hide=true
WIDGET.unFocus(true)
end
end
local scene={} local scene={}
function scene.sceneInit(org) function scene.sceneInit(org)
@@ -25,8 +58,10 @@ function scene.sceneInit(org)
lastUpstreamTime=0 lastUpstreamTime=0
upstreamProgress=1 upstreamProgress=1
if org=="setting_game"then if org=='setting_game'then NET.changeConfig()end
NET.changeConfig() if NET.streamRoomID then
NET.wsconn_stream()
NET.streamRoomID=false
end end
end end
function scene.sceneBack() function scene.sceneBack()
@@ -36,7 +71,8 @@ end
scene.mouseDown=NULL scene.mouseDown=NULL
function scene.mouseMove(x,y)netPLY.mouseMove(x,y)end function scene.mouseMove(x,y)netPLY.mouseMove(x,y)end
function scene.touchDown(x,y) function scene.touchDown(x,y)
if not playing or noTouch then return end if not playing then netPLY.mouseMove(x,y)return end
if noTouch then return end
local t=VK.on(x,y) local t=VK.on(x,y)
if t then if t then
@@ -52,9 +88,8 @@ function scene.touchUp(x,y)
VK.release(n) VK.release(n)
end end
end end
function scene.touchMove(x,y) function scene.touchMove()
if not playing then netPLY.mouseMove(x,y)return end if touchMoveLastFrame or not playing or noTouch then return end
if touchMoveLastFrame or noTouch then return end
touchMoveLastFrame=true touchMoveLastFrame=true
local L=tc.getTouches() local L=tc.getTouches()
@@ -78,33 +113,27 @@ function scene.touchMove(x,y)
end end
function scene.keyDown(key) function scene.keyDown(key)
if key=="escape"then if key=="escape"then
if TIME()-lastBackTime<1 then if not inputBox.hide then
NET.signal_quit() scene.keyDown("switchChat")
else else
lastBackTime=TIME() _quit()
LOG.print(text.sureQuit,'warn')
end end
elseif key=="return"then elseif key=="return"then
if inputBox.hide then local mes=STRING.trim(inputBox:getText())
textBox.hide=false if not inputBox.hide then
inputBox.hide=false if #mes>0 then
TASK.new(function()YIELD()WIDGET.sel=inputBox end)
enableTextInput()
else
local mes=STRING.trim(inputBox:getText())
if mes and #mes>0 then
NET.sendMessage(mes) NET.sendMessage(mes)
inputBox:clear() inputBox:clear()
elseif #EDITING==0 then elseif #EDITING==0 then
textBox.hide=true _switchChat()
inputBox.hide=true
WIDGET.sel=nil
kb.setTextInput(false)
end end
else
_switchChat()
end end
elseif not inputBox.hide then elseif not inputBox.hide then
WIDGET.sel=inputBox print(1)
WIDGET.keyPressed(key) WIDGET.focus(inputBox)
inputBox:keypress(key)
elseif playing then elseif playing then
if not playing or noKey then return end if not playing or noKey then return end
local k=keyMap.keyboard[key] local k=keyMap.keyboard[key]
@@ -114,11 +143,12 @@ function scene.keyDown(key)
end end
else else
if key=="space"then if key=="space"then
NET.signal_ready(not netPLY.getSelfReady()) if netPLY.getSelfJoinMode()==0 then
elseif key=="s"then (kb.isDown("lctrl","rctrl","lalt","ralt")and _setSpectate or _setReady)()
if not(netPLY.getSelfReady()or NET.getlock('ready'))then else
SCN.go('setting_game') _setCancel()
end end
_gotoSetting()
end end
end end
end end
@@ -175,11 +205,10 @@ function scene.socketRead(cmd,d)
if not playing then if not playing then
playing=true playing=true
love.keyboard.setKeyRepeat(false) love.keyboard.setKeyRepeat(false)
netPLY.resetState()
netPLY.mouseMove(0,0)
lastUpstreamTime=0 lastUpstreamTime=0
upstreamProgress=1 upstreamProgress=1
resetGameData('n',d.seed) resetGameData('n',NET.seed)
netPLY.mouseMove(0,0)
else else
LOG.print("Redundant [Go]",'warn') LOG.print("Redundant [Go]",'warn')
end end
@@ -194,10 +223,11 @@ function scene.socketRead(cmd,d)
end end
end end
if winnerUID then if winnerUID then
TEXT.show(text.champion:gsub("$1",netPLY.getUsername(winnerUID)),640,260,80,'zoomout',.26) TEXT.show(text.champion:gsub("$1",USERS.getUsername(winnerUID)),640,260,80,'zoomout',.26)
end end
netPLY.resetState()
elseif cmd=='stream'then elseif cmd=='stream'then
if d.uid~=USER.uid and playing then if d.uid~=USER.uid then
for _,P in next,PLAYERS do for _,P in next,PLAYERS do
if P.uid==d.uid then if P.uid==d.uid then
local res,stream=pcall(love.data.decode,'string','base64',d.stream) local res,stream=pcall(love.data.decode,'string','base64',d.stream)
@@ -206,9 +236,11 @@ function scene.socketRead(cmd,d)
else else
LOG.print("Bad stream from "..P.username.."#"..P.uid,30) LOG.print("Bad stream from "..P.username.."#"..P.uid,30)
end end
break
end end
end end
end end
end end
end end
@@ -230,15 +262,19 @@ function scene.update(dt)
checkWarning() checkWarning()
--Upload stream --Upload stream
if P1.frameRun-lastUpstreamTime>8 then if not NET.spectate and P1.frameRun-lastUpstreamTime>8 then
local stream local stream
stream,upstreamProgress=DATA.dumpRecording(GAME.rep,upstreamProgress) if not GAME.rep[upstreamProgress]then
if #stream>0 then
NET.uploadRecStream(stream)
else
ins(GAME.rep,P1.frameRun) ins(GAME.rep,P1.frameRun)
ins(GAME.rep,0) ins(GAME.rep,0)
end end
stream,upstreamProgress=DATA.dumpRecording(GAME.rep,upstreamProgress)
if #stream%3==1 then
stream=stream.."\0\0"
elseif #stream%3==2 then
stream=stream.."\0\0\0\0"
end
NET.uploadRecStream(stream)
lastUpstreamTime=PLAYERS[1].alive and P1.frameRun or 1e99 lastUpstreamTime=PLAYERS[1].alive and P1.frameRun or 1e99
end end
else else
@@ -260,6 +296,12 @@ function scene.draw()
--Warning --Warning
drawWarning() drawWarning()
if NET.spectate then
setFont(30)
gc_setColor(.2,1,0,.8)
gc_print(text.spectating,940,0)
end
else else
--Users --Users
netPLY.draw() netPLY.draw()
@@ -267,24 +309,24 @@ function scene.draw()
--Ready & Set mark --Ready & Set mark
setFont(50) setFont(50)
if NET.allReady then if NET.allReady then
gc.setColor(0,1,.5,.9) gc_setColor(0,1,.5,.9)
mStr(text.ready,640,15) mStr(text.ready,640,15)
elseif NET.connectingStream then elseif NET.connectingStream then
gc.setColor(.1,1,.8,.9) gc_setColor(.1,1,.8,.9)
mStr(text.connStream,640,15) mStr(text.connStream,640,15)
elseif NET.waitingStream then elseif NET.waitingStream then
gc.setColor(0,.8,1,.9) gc_setColor(0,.8,1,.9)
mStr(text.waitStream,640,15) mStr(text.waitStream,640,15)
end end
--Room info. --Room info.
gc.setColor(1,1,1) gc_setColor(1,1,1)
setFont(25) setFont(25)
gc.printf(NET.roomInfo.name,0,685,1270,'right') gc.printf(NET.roomState.roomInfo.name,0,685,1270,'right')
setFont(40) setFont(40)
gc.print(netPLY.getCount().."/"..NET.roomInfo.capacity,70,655) gc.print(netPLY.getCount().."/"..NET.roomState.capacity,70,655)
if NET.roomInfo.private then gc.draw(IMG.lock,30,668)end if NET.roomState.private then gc.draw(IMG.lock,30,668)end
if NET.roomInfo.start then gc.setColor(0,1,0)gc.print(text.started,230,655)end if NET.roomState.start then gc_setColor(0,1,0)gc_print(text.started,230,655)end
--Profile --Profile
drawSelfProfile() drawSelfProfile()
@@ -296,32 +338,40 @@ function scene.draw()
--New message --New message
if textBox.new then if textBox.new then
setFont(40) setFont(40)
gc.setColor(1,1,0) gc_setColor(1,1,0)
gc.print("M",430,10) gc.print("M",430,10)
end end
end end
scene.widgetList={ scene.widgetList={
textBox, textBox,
inputBox, inputBox,
WIDGET.newKey{name="setting",fText=TEXTURE.setting,x=1200,y=160,w=90,h=90,code=pressKey"s",hideF=function()return playing or netPLY.getSelfReady()or NET.getlock('ready')end}, WIDGET.newKey{name="setting",fText=TEXTURE.setting,x=1200,y=160,w=90,h=90,code=_gotoSetting,hideF=function()return playing or netPLY.getSelfReady()or NET.getlock('ready')end},
WIDGET.newKey{name="ready",x=1060,y=630,w=300,h=80,color='lB',font=40,code=pressKey"space", WIDGET.newKey{name="ready",x=1060,y=510,w=370,h=90,color='lG',font=35,code=_setReady,
hideF=function() hideF=function()
return return
playing or playing or
NET.serverGaming or NET.roomState.start or
netPLY.getSelfReady()or netPLY.getSelfReady() or
NET.getlock('ready') NET.getlock('ready')
end}, end},
WIDGET.newKey{name="cancel",x=1060,y=630,w=300,h=80,color='H',font=40,code=pressKey"space", WIDGET.newKey{name="spectate",x=1060,y=610,w=370,h=90,color='lO',font=35,code=_setSpectate,
hideF=function() hideF=function()
return return
playing or playing or
NET.serverGaming or NET.roomState.start or
not netPLY.getSelfReady()or netPLY.getSelfReady() or
NET.getlock('ready') NET.getlock('ready')
end}, end},
WIDGET.newKey{name="hideChat",fText="...",x=380,y=35,w=60,font=35,code=pressKey"return"}, WIDGET.newKey{name="cancel",x=1060,y=560,w=370,h=120,color='lH',font=40,code=_setCancel,
WIDGET.newKey{name="quit",fText="X",x=900,y=35,w=60,font=40,code=pressKey"escape"}, hideF=function()
return
playing or
NET.roomState.start or
not netPLY.getSelfReady() or
NET.getlock('ready')
end},
WIDGET.newKey{name="hideChat",fText="...",x=380,y=35,w=60,font=35,code=_switchChat},
WIDGET.newKey{name="quit",fText="X",x=900,y=35,w=60,font=40,code=_quit},
} }
return scene return scene

View File

@@ -8,8 +8,20 @@ local scrollPos,selected
local fetchTimer local fetchTimer
local lastCreateRoomTime=0 local lastCreateRoomTime=0
--[[room={
rid="qwe",
roomInfo={
name="MrZ's room",
type="classic",
version=1409,
},
private=false,
start=false,
count=4,
capacity=5,
}]]
local function fetchRoom() local function fetchRoom()
fetchTimer=5 fetchTimer=10
NET.fetchRoom() NET.fetchRoom()
end end
@@ -17,9 +29,6 @@ local scene={}
function scene.sceneInit() function scene.sceneInit()
BG.set() BG.set()
NET.allReady=false
NET.connectingStream=false
NET.waitingStream=false
scrollPos=0 scrollPos=0
selected=1 selected=1
fetchRoom() fetchRoom()
@@ -30,7 +39,7 @@ function scene.wheelMoved(_,y)
end end
function scene.keyDown(k) function scene.keyDown(k)
if k=="r"then if k=="r"then
if fetchTimer<=3.26 then if fetchTimer<=7 then
fetchRoom() fetchRoom()
end end
elseif k=="s"then elseif k=="s"then
@@ -74,27 +83,26 @@ function scene.keyDown(k)
end end
elseif k=="return"then elseif k=="return"then
if NET.getlock('fetchRoom')or not NET.roomList[selected]then return end if NET.getlock('fetchRoom')or not NET.roomList[selected]then return end
if NET.roomList[selected].private then local R=NET.roomList[selected]
LOG.print("Can't enter private room now",'message') if R.roomInfo.version~=VERSION.short then LOG.print("Version doesn't match",'message')return end
return if R.private then LOG.print("Can't enter private room now",'message')return end
end NET.enterRoom(R)--,password
NET.enterRoom(NET.roomList[selected])--,password
end end
end end
end end
function scene.mouseMove(x,y,_,dy) function scene.mouseMove(x,y,_,dy)
if ms.isDown(1)and x>50 and x<1110 and y>110 and y<510 then if ms.isDown(1)and x>50 and x<850 and y>110 and y<510 then
scene.wheelMoved(0,dy/40) scene.wheelMoved(0,dy/40)
end end
end end
function scene.touchMove(x,y,_,dy) function scene.touchMove(x,y,_,dy)
if x>50 and x<1110 and y>110 and y<510 then if x>50 and x<850 and y>110 and y<510 then
scene.wheelMoved(0,dy/40) scene.wheelMoved(0,dy/40)
end end
end end
function scene.mouseClick(x,y) function scene.mouseClick(x,y)
if x>50 and x<1110 then if x>50 and x<850 then
y=int((y-70)/40) y=int((y-70)/40)
if y>=1 and y<=10 then if y>=1 and y<=10 then
local s=int(y+scrollPos) local s=int(y+scrollPos)
@@ -129,46 +137,64 @@ end
function scene.draw() function scene.draw()
--Fetching timer --Fetching timer
gc.setColor(1,1,1,.12) gc.setColor(1,1,1,.12)
gc.arc('fill','pie',300,620,60,-1.5708,-1.5708-1.2566*fetchTimer) gc.arc('fill','pie',300,620,60,-1.5708,-1.5708-.6283*fetchTimer)
--Room list --Room list
gc.setColor(1,1,1) gc.setColor(1,1,1)
gc.setLineWidth(2) gc.setLineWidth(2)
gc.rectangle('line',50,110,1060,400) gc.rectangle('line',50,110,800,400)
local roomCount=#NET.roomList local roomCount=#NET.roomList
if roomCount>0 then if roomCount>0 then
setFont(35) if roomCount>10 then
local len=400*10/roomCount
gc.rectangle('fill',837,110+(400-len)*scrollPos/(roomCount-10),12,len)
end
gc.push('transform') gc.push('transform')
gc.stencil(roomListStencil,'replace',1) gc.stencil(roomListStencil,'replace',1)
gc.setStencilTest('equal',1) gc.setStencilTest('equal',1)
gc.translate(0,scrollPos%1*-40) gc.translate(0,scrollPos%1*-40)
setFont(35)
local pos=int(scrollPos) local pos=int(scrollPos)
for i=1,math.min(11,roomCount-pos)do for i=1,math.min(11,roomCount-pos)do
local R=NET.roomList[pos+i] local R=NET.roomList[pos+i]
if pos+i==selected then if pos+i==selected then
gc.setColor(1,1,1,.3) gc.setColor(1,1,1,.3)
gc.rectangle('fill',50,70+40*i,1060,40) gc.rectangle('fill',50,70+40*i,800,40)
end
if R.start then
gc.setColor(0,1,0)
gc.print(text.started,660,66+40*i)
end end
gc.setColor(1,1,1)
if R.private then gc.draw(IMG.lock,60,75+40*i)end
gc.print(R.count.."/"..R.capacity,720,66+40*i)
gc.setColor(.9,.9,1) gc.setColor(.9,.9,1)
gc.print(pos+i,95,66+40*i) gc.print(pos+i,95,66+40*i)
gc.setColor(1,1,.7)
gc.print(R.name,250,66+40*i) if R.start then
gc.setColor(1,1,1) gc.setColor(0,.4,.1)
gc.printf(R.type,430,66+40*i,500,'right') else
gc.print(R.count.."/"..R.capacity,980,66+40*i) gc.setColor(1,1,.7)
if R.private then
gc.draw(IMG.lock,59,75+40*i)
end end
gc.print(R.roomInfo.name,250,66+40*i)
end end
gc.setStencilTest() gc.setStencilTest()
gc.pop() gc.pop()
if roomCount>10 then
local len=400*10/roomCount gc.setColor(1,1,1)
gc.rectangle('fill',1218,110+(400-len)*scrollPos/(roomCount-10),12,len) gc.rectangle('line',860,240,385,270)
if NET.roomList[selected]then
local R=NET.roomList[selected]
setFont(25)
gc.print(R.roomInfo.type,870,265)
gc.setColor(1,1,.7)
gc.printf(R.roomInfo.name,870,240,365)
setFont(20)
if R.start then
gc.setColor(0,1,.2)
gc.print(text.started,870,475)
end
if R.roomInfo.version~=VERSION.short then
gc.setColor(1,.2,0)
gc.printf(R.roomInfo.version,870,475,365,'right')
end
end end
end end
@@ -181,9 +207,9 @@ end
scene.widgetList={ scene.widgetList={
WIDGET.newKey{name="setting",fText=TEXTURE.setting,x=1200,y=160,w=90,h=90,code=pressKey"s"}, WIDGET.newKey{name="setting",fText=TEXTURE.setting,x=1200,y=160,w=90,h=90,code=pressKey"s"},
WIDGET.newText{name="refreshing",x=580,y=255,font=45,hideF=function()return not NET.getlock('fetchRoom')end}, WIDGET.newText{name="refreshing",x=450,y=255,font=45,hideF=function()return not NET.getlock('fetchRoom')end},
WIDGET.newText{name="noRoom", x=580,y=260,font=40,hideF=function()return #NET.roomList>0 or NET.getlock('fetchRoom')end}, WIDGET.newText{name="noRoom", x=450,y=260,font=40,hideF=function()return #NET.roomList>0 or NET.getlock('fetchRoom')end},
WIDGET.newKey{name="refresh", x=300,y=620,w=140,h=140,font=35,code=fetchRoom,hideF=function()return fetchTimer>3.26 end}, WIDGET.newKey{name="refresh", x=300,y=620,w=140,h=140,font=35,code=fetchRoom,hideF=function()return fetchTimer>7 end},
WIDGET.newKey{name="new", x=500,y=620,w=140,h=140,font=20,code=pressKey"n"}, WIDGET.newKey{name="new", x=500,y=620,w=140,h=140,font=20,code=pressKey"n"},
WIDGET.newKey{name="new2", x=700,y=620,w=140,h=140,font=20,code=pressKey"m"}, WIDGET.newKey{name="new2", x=700,y=620,w=140,h=140,font=20,code=pressKey"m"},
WIDGET.newKey{name="join", x=900,y=620,w=140,h=140,font=40,code=pressKey"return",hideF=function()return #NET.roomList==0 or NET.getlock('enterRoom')end}, WIDGET.newKey{name="join", x=900,y=620,w=140,h=140,font=40,code=pressKey"return",hideF=function()return #NET.roomList==0 or NET.getlock('enterRoom')end},

View File

@@ -34,7 +34,7 @@ function scene.sceneInit(org)
local P=PLAYERS[1] local P=PLAYERS[1]
local S=P.stat local S=P.stat
timer=org=="game"and 0 or 50 timer=org=='game'and 0 or 50
local frameLostRate=(S.frame/S.time/60-1)*100 local frameLostRate=(S.frame/S.time/60-1)*100
form={ form={

View File

@@ -17,10 +17,6 @@ local function register()
NET.register(username,email,password) NET.register(username,email,password)
end end
function scene.sceneInit()
enableTextInput()
end
scene.widgetList={ scene.widgetList={
WIDGET.newText{name="title", x=80, y=50,font=70,align='L'}, WIDGET.newText{name="title", x=80, y=50,font=70,align='L'},
WIDGET.newButton{name="login", x=1140, y=100,w=170,h=80,color='lY',code=function()SCN.swapTo('login','swipeL')end}, WIDGET.newButton{name="login", x=1140, y=100,w=170,h=80,color='lY',code=function()SCN.swapTo('login','swipeL')end},

View File

@@ -76,7 +76,7 @@ function scene.touchUp()
end end
end end
function scene.touchMove(_,_,dx,dy) function scene.touchMove(_,_,dx,dy)
if selected and not WIDGET.sel then if selected and WIDGET.isFocus(false)then
local B=VK_org[selected] local B=VK_org[selected]
B.x,B.y=B.x+dx,B.y+dy B.x,B.y=B.x+dx,B.y+dy
end end
@@ -84,8 +84,8 @@ end
function scene.draw() function scene.draw()
gc.setColor(1,1,1) gc.setColor(1,1,1)
gc.setLineWidth(7)gc.rectangle('line',340,15,600,690) gc.setLineWidth(3)
gc.setLineWidth(3)gc.rectangle('line',490,85,300,600) gc.rectangle('line',490,85,300,600)
VK.preview(selected) VK.preview(selected)
if snapUnit>=10 then if snapUnit>=10 then
gc.setLineWidth(3) gc.setLineWidth(3)
@@ -193,11 +193,8 @@ scene.widgetList={
selected=false selected=false
end}, end},
WIDGET.newSelector{name="snap", x=750,y=90,w=200,h=80,color='Y',list={1,10,20,40,60,80},disp=function()return snapUnit end,code=function(i)snapUnit=i end}, WIDGET.newSelector{name="snap", x=750,y=90,w=200,h=80,color='Y',list={1,10,20,40,60,80},disp=function()return snapUnit end,code=function(i)snapUnit=i end},
WIDGET.newButton{name="option", x=530,y=190,w=200,h=80,font=40, WIDGET.newButton{name="option", x=530,y=190,w=200,h=80,font=40,code=function()SCN.go('setting_touchSwitch')end},
code=function() WIDGET.newButton{name="back", x=750,y=190,w=200,h=80,font=35,code=backScene},
SCN.go('setting_touchSwitch')
end},
WIDGET.newButton{name="back", x=750,y=190,w=200,h=70,font=35,code=backScene},
WIDGET.newKey{name="save1", x=475,y=290,w=90,h=70,code=save1}, WIDGET.newKey{name="save1", x=475,y=290,w=90,h=70,code=save1},
WIDGET.newKey{name="load1", x=585,y=290,w=90,h=70,code=load1}, WIDGET.newKey{name="load1", x=585,y=290,w=90,h=70,code=load1},
WIDGET.newKey{name="save2", x=695,y=290,w=90,h=70,code=save2}, WIDGET.newKey{name="save2", x=695,y=290,w=90,h=70,code=save2},
@@ -214,6 +211,7 @@ scene.widgetList={
hideF=function() hideF=function()
return not selected return not selected
end}, end},
WIDGET.newKey{name="shape",x=640,y=600,w=200,h=80,code=function()SETTING.VKSkin=VK.nextShape()end},
} }
return scene return scene

View File

@@ -13,41 +13,42 @@ scene.widgetList={
WIDGET.newButton{name="sound", x=200,y=80,w=240,h=80,color='lC',font=35,code=swapScene("setting_sound",'swipeR')}, WIDGET.newButton{name="sound", x=200,y=80,w=240,h=80,color='lC',font=35,code=swapScene("setting_sound",'swipeR')},
WIDGET.newButton{name="game", x=1080,y=80,w=240,h=80,color='lC',font=35,code=swapScene("setting_game",'swipeL')}, WIDGET.newButton{name="game", x=1080,y=80,w=240,h=80,color='lC',font=35,code=swapScene("setting_game",'swipeL')},
WIDGET.newSwitch{name="block", x=350,y=160,disp=SETval("block"),code=SETrev("block")}, WIDGET.newSwitch{name="block", x=270,y=160,disp=SETval("block"),code=SETrev("block")},
WIDGET.newSwitch{name="smooth", x=350,y=210,disp=SETval("smooth"),code=SETrev("smooth")}, WIDGET.newSwitch{name="smooth", x=270,y=210,disp=SETval("smooth"),code=SETrev("smooth")},
WIDGET.newSwitch{name="upEdge", x=350,y=260,disp=SETval("upEdge"),code=SETrev("upEdge")}, WIDGET.newSwitch{name="upEdge", x=270,y=260,disp=SETval("upEdge"),code=SETrev("upEdge")},
WIDGET.newSwitch{name="bagLine", x=350,y=310,disp=SETval("bagLine"),code=SETrev("bagLine")}, WIDGET.newSwitch{name="bagLine", x=270,y=310,disp=SETval("bagLine"),code=SETrev("bagLine")},
WIDGET.newSlider{name="ghost", x=700,y=180,w=380,unit=.6, disp=SETval("ghost"),show="percent",code=SETsto("ghost")}, WIDGET.newSlider{name="ghost", x=610,y=180,w=320,unit=.6, disp=SETval("ghost"),show="percent",code=SETsto("ghost")},
WIDGET.newSlider{name="grid", x=700,y=240,w=380,unit=.4, disp=SETval("grid"),show="percent", code=SETsto("grid")}, WIDGET.newSlider{name="grid", x=610,y=240,w=320,unit=.4, disp=SETval("grid"),show="percent", code=SETsto("grid")},
WIDGET.newSlider{name="center", x=700,y=300,w=380,unit=1, disp=SETval("center"), code=SETsto("center")}, WIDGET.newSlider{name="center", x=610,y=300,w=320,unit=1, disp=SETval("center"), code=SETsto("center")},
WIDGET.newSlider{name="lockFX", x=220,y=365,w=380,unit=5, disp=SETval("lockFX"), code=SETsto("lockFX")}, WIDGET.newSlider{name="lockFX", x=220,y=365,w=380,unit=5, disp=SETval("lockFX"), code=SETsto("lockFX")},
WIDGET.newSlider{name="dropFX", x=220,y=405,w=380,unit=5, disp=SETval("dropFX"), code=SETsto("dropFX")}, WIDGET.newSlider{name="dropFX", x=220,y=415,w=380,unit=5, disp=SETval("dropFX"), code=SETsto("dropFX")},
WIDGET.newSlider{name="moveFX", x=220,y=445,w=380,unit=5, disp=SETval("moveFX"), code=SETsto("moveFX")}, WIDGET.newSlider{name="moveFX", x=220,y=465,w=380,unit=5, disp=SETval("moveFX"), code=SETsto("moveFX")},
WIDGET.newSlider{name="clearFX", x=220,y=485,w=380,unit=5, disp=SETval("clearFX"), code=SETsto("clearFX")}, WIDGET.newSlider{name="clearFX", x=220,y=515,w=380,unit=5, disp=SETval("clearFX"), code=SETsto("clearFX")},
WIDGET.newSlider{name="splashFX", x=220,y=525,w=380,unit=5, disp=SETval("splashFX"),code=SETsto("splashFX")}, WIDGET.newSlider{name="splashFX", x=220,y=565,w=380,unit=5, disp=SETval("splashFX"),code=SETsto("splashFX")},
WIDGET.newSlider{name="shakeFX", x=220,y=565,w=380,unit=5, disp=SETval("shakeFX"), code=SETsto("shakeFX")}, WIDGET.newSlider{name="shakeFX", x=220,y=615,w=380,unit=5, disp=SETval("shakeFX"), code=SETsto("shakeFX")},
WIDGET.newSlider{name="atkFX", x=220,y=605,w=380,unit=5, disp=SETval("atkFX"), code=SETsto("atkFX")}, WIDGET.newSlider{name="atkFX", x=220,y=665,w=380,unit=5, disp=SETval("atkFX"), code=SETsto("atkFX")},
WIDGET.newSelector{name="frame", x=410,y=660,w=360,list={8,10,13,17,22,29,37,47,62,80,100},disp=SETval("frameMul"),code=SETsto("frameMul")}, WIDGET.newSelector{name="frame", x=830,y=640,w=360,list={8,10,13,17,22,29,37,47,62,80,100},disp=SETval("frameMul"),code=SETsto("frameMul")},
WIDGET.newSwitch{name="text", x=900,y=360,disp=SETval("text"), code=SETrev("text")}, WIDGET.newSwitch{name="text", x=900,y=360,disp=SETval("text"), code=SETrev("text")},
WIDGET.newSwitch{name="score", x=900,y=410,disp=SETval("score"), code=SETrev("score")}, WIDGET.newSwitch{name="score", x=900,y=410,disp=SETval("score"), code=SETrev("score")},
WIDGET.newSwitch{name="warn", x=900,y=460,disp=SETval('warn'), code=SETrev('warn')}, WIDGET.newSwitch{name="bufferWarn", x=900,y=460,disp=SETval('bufferWarn'), code=SETrev('bufferWarn')},
WIDGET.newSwitch{name="bufferWarn", x=900,y=510,disp=SETval('bufferWarn'), code=SETrev('bufferWarn')}, WIDGET.newSwitch{name="showSpike", x=900,y=510,disp=SETval('showSpike'), code=SETrev('showSpike')},
WIDGET.newSwitch{name="highCam", x=900,y=560,disp=SETval("highCam"), code=SETrev("highCam")}, WIDGET.newSwitch{name="highCam", x=900,y=560,disp=SETval("highCam"), code=SETrev("highCam")},
WIDGET.newSwitch{name="nextPos", x=1180,y=360,disp=SETval("nextPos"), code=SETrev("nextPos")}, WIDGET.newSwitch{name="nextPos", x=1180,y=260,disp=SETval("nextPos"), code=SETrev("nextPos")},
WIDGET.newSwitch{name="fullscreen", x=1180,y=410,disp=SETval("fullscreen"), code=switchFullscreen}, WIDGET.newSwitch{name="fullscreen", x=1180,y=310,disp=SETval("fullscreen"), code=switchFullscreen},
WIDGET.newSwitch{name="power", x=1180,y=460,disp=SETval("powerInfo"), code=SETrev("powerInfo")}, WIDGET.newSwitch{name="power", x=1180,y=360,disp=SETval("powerInfo"), code=SETrev("powerInfo")},
WIDGET.newSwitch{name="clickFX", x=1180,y=510,disp=SETval("clickFX"), code=SETrev("clickFX")}, WIDGET.newSwitch{name="clickFX", x=1180,y=410,disp=SETval("clickFX"), code=SETrev("clickFX")},
WIDGET.newSwitch{name="bg", x=1180,y=560,disp=SETval("bg"), WIDGET.newSwitch{name="bg", x=1180,y=460,disp=SETval("bg"),
code=function() code=function()
BG.set('none') BG.set('none')
SETTING.bg=not SETTING.bg SETTING.bg=not SETTING.bg
BG.set() BG.set()
end}, end},
WIDGET.newSwitch{name="clean", x=990,y=640,font=35,disp=SETval("cleanCanvas"),code=SETrev("cleanCanvas")}, WIDGET.newSwitch{name="clean", x=1180,y=510,disp=SETval("cleanCanvas"),code=SETrev("cleanCanvas")},
WIDGET.newSwitch{name="warn", x=1180,y=560,disp=SETval("warn"), code=SETrev("warn")},
WIDGET.newButton{name="back", x=1140,y=640,w=170,h=80,font=40,code=backScene}, WIDGET.newButton{name="back", x=1140,y=640,w=170,h=80,font=40,code=backScene},
} }

View File

@@ -12,17 +12,52 @@ return STRING.split([=[
Tetra-link; 速算(前缀后缀表达式,二八十六进制) Tetra-link; 速算(前缀后缀表达式,二八十六进制)
连连看; 求合体; 坦克大战; 扫雷; 接水管 连连看; 求合体; 坦克大战; 扫雷; 接水管
其他未来内容: 其他未来内容:
详细开房界面; 自适应UI; 高级自定义序列; 对战结束后展示数据和排行
重做模式选择UI; MOD的UI; 可滚动控件模块(自定义/设置UI)
XRS; 移动n格+硬降复合操作键; 更好的手柄支持 XRS; 移动n格+硬降复合操作键; 更好的手柄支持
自适应UI; 高级自定义序列; 对战结束后展示数据和排行
重做模式选择UI, MOD的UI, 自定义游戏UI
区分各种消除(隔断/架空/混合/彩色/穿墙) 区分各种消除(隔断/架空/混合/彩色/穿墙)
更复杂的垃圾行(数量/等待时间/抵消倍率/洞数/连接/炸弹/厚度)
可调场地宽度; 左右三按键; 手势操作; 特殊控件(虚拟摇杆等); 切换高低镜头键 可调场地宽度; 左右三按键; 手势操作; 特殊控件(虚拟摇杆等); 切换高低镜头键
DAS系统和Deepdrop系统更细节的选项; spike计数器 更复杂的垃圾行(数量/等待时间/抵消倍率/洞数/连接/炸弹/厚度)
成就系统; 更强的主题系统; 多方块; 3D背景 DAS系统和Deepdrop系统更细节的选项
工程编译到字节码; task-Z(新AI); 开房机制修改 成就系统; 更强的主题系统; 3D背景
等级系统; 旁观; 收集向抽奖玩法 工程编译到字节码; task-Z(新AI)
录像回放菜单; 跳帧开关; 教学关; 超60帧; 热更新 等级系统; 收集向抽奖玩法; 教学关
录像回放菜单; 跳帧开关; 多方块; 超60帧; 热更新
0.15.1: 耀斑 Flare
新增:
允许开局跳过若干next时,倒计时数字颜色会略有不同
改动:
微调联网房间内准备前ui,修改键盘准备/观战快捷键
混战模式和联网对战允许开局跳块
优化爆发累计和缓冲预警的画面效果
优化开局倒计时画面效果
修复自定义-消除模式左侧信息显示问题
修复:
一处cc库相关的报错
[服务器]观战玩家会影响游戏结束判定
0.15.0: 超新星 Supernova
新增:
[双端]观战功能
spike计数器
全新房间列表ui
重新启用临界时间(基于帧)
新增虚拟按键形状设置
改动:
主菜单按钮行为更容易理解,添加连接音效和连接成功音效
移除next和hold栏上的文本
聊天窗交互更自然
词典添加游戏官网词条
修改默认空用户名
更新cc模块
代码:
升级控件模块
升级本地和服务器提供的房间数据格式
修复:
结算显示胜利者时可能报错
"游戏中"标记会被带到别的房间
命令行执行空白字符串报错
0.14.8: 冰激凌 Icecream 0.14.8: 冰激凌 Icecream
新增: 新增:

View File

@@ -13,7 +13,7 @@ local function loadAvatar(path)
end end
local emptyUser={ local emptyUser={
username="Player", username="_Stacker",
motto="", motto="",
hash="", hash="",
new=false, new=false,

View File

@@ -1,8 +1,34 @@
local gc=love.graphics local gc=love.graphics
local gc_draw,gc_setColor,gc_setLineWidth=gc.draw,gc.setColor,gc.setLineWidth
local next=next local next=next
local SETTING,TIME=SETTING,TIME local SETTING,TIME=SETTING,TIME
local VK_org=VK_org local VK_org=VK_org
local skin=1
local r=10
local buttonImages={
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98},{'dCirc',100,100,90}},
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98,8},{'dCirc',100,100,90,8}},
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98,6},{'dCirc',100,100,90,6}},
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98,4},{'dCirc',100,100,89,4}},
DOGC{200,200,{'setLW',4},{'dRect',31,31,138,138},{'dRect',39,39,122,122}},
}
local rippleImages={
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98}},
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98,8}},
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98,6}},
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98,4}},
DOGC{200,200,{'setLW',4},{'dRect',31,31,138,138}},
}
local holdImages={
DOGC{200,200,{'fCirc',100,100,86}},
DOGC{200,200,{'fCirc',100,100,86,8}},
DOGC{200,200,{'fCirc',100,100,85,6}},
DOGC{200,200,{'fCirc',100,100,83,4}},
DOGC{200,200,{'fRect',43,43,114,114}},
}
--Virtualkey icons --Virtualkey icons
local VKIcon={} local VKIcon={}
gc.setDefaultFilter('nearest','nearest') gc.setDefaultFilter('nearest','nearest')
@@ -69,6 +95,14 @@ function VK.release(id)
keys[id].isDown=false keys[id].isDown=false
end end
function VK.setShape(s)
skin=s
end
function VK.nextShape()
skin=skin%#buttonImages+1
return skin
end
function VK.switchKey(id,on) function VK.switchKey(id,on)
keys[id].ava=on keys[id].ava=on
end end
@@ -100,47 +134,53 @@ function VK.update()
end end
end end
local gc_circle,gc_draw,gc_setColor,gc_setLineWidth=gc.circle,gc.draw,gc.setColor,gc.setLineWidth
function VK.draw() function VK.draw()
if not SETTING.VKSwitch then return end if not SETTING.VKSwitch then return end
local a=SETTING.VKAlpha local a=SETTING.VKAlpha
local buttonImage=buttonImages[skin]
local rippleImage=rippleImages[skin]
local holdImage=holdImages[skin]
if SETTING.VKIcon then if SETTING.VKIcon then
for i,B in next,keys do for i,B in next,keys do
if B.ava then if B.ava then
local r=B.r
--Button outline --Button outline
gc_setColor(1,1,1,a) gc_setColor(1,1,1,a)
gc_setLineWidth(B.r*.07) gc_setLineWidth(r*.07)
gc_circle('line',B.x,B.y,B.r,10) gc_draw(buttonImage,B.x,B.y,nil,r*.01,nil,100,100)
--Icon --Icon
local _=B.pressTime local _=B.pressTime
gc_setColor(1,1,1,a) gc_setColor(1,1,1,a)
gc_draw(VKIcon[i],B.x,B.y,nil,B.r*.026+_*.08,nil,18,18) gc_draw(VKIcon[i],B.x,B.y,nil,r*.024+_*.06,nil,18,18)
--Ripple --Ripple
if _>0 then if _>0 then
gc_setColor(1,1,1,a*_*.08) gc_setColor(1,1,1,a*_*.08)
gc_circle('line',B.x,B.y,B.r*(1.4-_*.04),10) local d=r*(1.4-_*.04)
gc_draw(rippleImage,B.x,B.y,nil,d*.01,nil,100,100)
end end
--Glow when press --Glow when press
if B.isDown then if B.isDown then
gc_setColor(1,1,1,a*.4) gc_setColor(1,1,1,a*.4)
gc_circle('fill',B.x,B.y,B.r*.94,10) gc_draw(holdImage,B.x,B.y,nil,r*.01,nil,100,100)
end end
end end
end end
else else
for _,B in next,keys do for _,B in next,keys do
if B.ava then if B.ava then
local r=B.r
gc_setColor(1,1,1,a) gc_setColor(1,1,1,a)
gc_setLineWidth(B.r*.07) gc_setLineWidth(r*.07)
gc_circle('line',B.x,B.y,B.r,10) gc_draw(buttonImage,B.x,B.y,nil,r*.01,nil,100,100)
local _=B.pressTime local _=B.pressTime
if _>0 then if _>0 then
gc_setColor(1,1,1,a*_*.08) gc_setColor(1,1,1,a*_*.08)
gc_circle('fill',B.x,B.y,B.r*.94,10) gc_draw(holdImage,B.x,B.y,nil,r*.01,nil,100,100)
gc_circle('line',B.x,B.y,B.r*(1.4-_*.04),10) local d=r*(1.4-_*.04)
gc_draw(rippleImage,B.x,B.y,nil,d*.01,nil,100,100)
end end
end end
end end
@@ -148,18 +188,21 @@ function VK.draw()
end end
function VK.preview(selected) function VK.preview(selected)
if not SETTING.VKSwitch then return end if not SETTING.VKSwitch then return end
for id,B in next,VK_org do local buttonImage=buttonImages[skin]
local holdImage=holdImages[skin]
for i,B in next,VK_org do
if B.ava then if B.ava then
local r=B.r
gc_setColor(1,1,1,SETTING.VKAlpha) gc_setColor(1,1,1,SETTING.VKAlpha)
gc_setLineWidth(B.r*.07) gc_setLineWidth(r*.07)
gc_circle('line',B.x,B.y,B.r,10) gc_draw(buttonImage,B.x,B.y,nil,r*.01,nil,100,100)
if selected==id and TIME()%.26<.13 then if selected==i and TIME()%.26<.13 then
gc_setColor(1,1,1,SETTING.VKAlpha*.62) gc_setColor(1,1,1,SETTING.VKAlpha*.62)
gc_circle('fill',B.x,B.y,B.r,10) gc_draw(holdImage,B.x,B.y,nil,r*.01,nil,100,100)
end end
if SETTING.VKIcon then if SETTING.VKIcon then
gc_setColor(1,1,1,SETTING.VKAlpha) gc_setColor(1,1,1,SETTING.VKAlpha)
gc_draw(VKIcon[id],B.x,B.y,nil,B.r*.025,nil,18,18) gc_draw(VKIcon[i],B.x,B.y,nil,r*.024,nil,18,18)
end end
end end
end end