Compare commits

...

23 Commits

Author SHA1 Message Date
MrZ626
4e073d1bb6 添加0.14.4更新日志和版本号 2021-04-13 00:34:53 +08:00
MrZ626
2fbb295490 修复小程序15p盲打颜色配置错误 2021-04-13 00:32:29 +08:00
MrZ626
b72631cd82 修复一个小程序入口名错误 2021-04-13 00:27:57 +08:00
MrZ626
832c09980a 修复小程序2048之前在删goto时造成的逻辑错误 2021-04-13 00:26:02 +08:00
MrZ626
ca68a8ef87 玩家死亡消息以服务器为准,录像不同步不再影响结算 2021-04-12 23:10:39 +08:00
MrZ626
0645cec207 修改可能导致ws尝试发送数字消息然后报错的一处代码 2021-04-12 21:38:20 +08:00
MrZ626
53dde3ec9e 更换催促等待提示音 2021-04-12 21:27:37 +08:00
MrZ626
df5c16e05f 对战房间的准备按钮颜色和文本会随状态改变 2021-04-12 21:25:11 +08:00
MrZ626
bb3bb938e8 新BGM:vacuum(用于节日主题),zday拆分为zday1和zday2 2021-04-12 21:13:02 +08:00
MrZ626
c196a2104e 修改隐形模式BGM配置 2021-04-12 21:06:14 +08:00
MrZ626
c78c596095 修复master-ph错误,使用新BGM:super7th 2021-04-12 20:59:52 +08:00
MrZ626
8d2d0f0b22 修复his序列模式算法错误 2021-04-12 20:52:49 +08:00
MrZ626
26d06e8f3a 添加触摸/点击特效开关 2021-04-12 20:39:21 +08:00
MrZ626
59eb8ae7f1 调整画面设置ui 2021-04-12 19:15:52 +08:00
MrZ626
7d932016b8 联网对战时禁用鼠标右键返回 2021-04-12 18:48:34 +08:00
MrZ626
998eb56348 调整存档更新代码 2021-04-12 12:57:57 +08:00
MrZ626
7837064e80 不再接受过老版本的存档,每次启动删除存档文件夹内裸露的文件 2021-04-12 12:55:22 +08:00
MrZ626
53745c61e5 修改注册时的合法邮箱格式 2021-04-12 02:37:13 +08:00
MrZ626
14adcff9dc splitStr模块可开关正则(默认不用) 2021-04-12 02:08:54 +08:00
MrZ626
7d67288766 修复O块在变形后hold失去名字和颜色属性 2021-04-12 00:25:28 +08:00
MrZ626
d904b126df 自定义场地默认使用智能画笔 2021-04-11 23:02:05 +08:00
MrZ626
649df9be49 修复催促准备音效在玩家准备后也会播放 2021-04-11 21:50:18 +08:00
MrZ626
4e49c1f80d 修复进游戏场景前收到部分socket消息会报错 2021-04-11 21:38:16 +08:00
33 changed files with 209 additions and 152 deletions

View File

@@ -124,7 +124,7 @@ function love.mousepressed(x,y,k,touch)
WIDGET.press(mx,my) WIDGET.press(mx,my)
end end
lastX,lastY=mx,my lastX,lastY=mx,my
SYSFX.newTap(3,mx,my,30) if SETTING.clickFX then SYSFX.newTap(3,mx,my,30)end
end end
function love.mousemoved(x,y,dx,dy,touch) function love.mousemoved(x,y,dx,dy,touch)
if touch then return end if touch then return end
@@ -194,7 +194,7 @@ function love.touchreleased(id,x,y)
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
if SCN.touchClick then SCN.touchClick(x,y)end if SCN.touchClick then SCN.touchClick(x,y)end
SYSFX.newTap(3,x,y,30) if SETTING.clickFX then SYSFX.newTap(3,x,y,30)end
end end
end end

View File

@@ -1,11 +1,19 @@
local find,sub=string.find,string.sub local find,sub=string.find,string.sub
return function(s,sep) return function(s,sep,regex)
local L={} local L={}
local p1,p2=1--start,target local p1,p2=1--start,target
while p1<=#s do if regex then
p2=find(s,sep,p1)or #s+1 while p1<=#s do
L[#L+1]=sub(s,p1,p2-1) p2=find(s,sep,p1)or #s+1
p1=p2+#sep L[#L+1]=sub(s,p1,p2-1)
p1=p2+#sep
end
else
while p1<=#s do
p2=find(s,sep,p1,true)or #s+1
L[#L+1]=sub(s,p1,p2-1)
p1=p2+#sep
end
end end
return L return L
end end

View File

@@ -31,9 +31,13 @@ function THEME.calculate(Y,M,D)
M=="04"and D=="01"and M=="04"and D=="01"and
"fool"or "fool"or
--Z day (Feb./Mar./Apr./May./June 26) --Z day (1) (Feb./Mar./Apr. 26)
math.abs(M-4)<=2 and D+0==26 and math.abs(M-3)<=1 and D=="26"and
"zday"or "zday1"or
--Z day (2) (May./June 26)
math.abs(M-5.5)<=1 and D=="26"and
"zday2"or
"classic" "classic"
end end
@@ -54,9 +58,12 @@ function THEME.set(theme)
LOG.print(" ★☆☆★",COLOR.red) LOG.print(" ★☆☆★",COLOR.red)
LOG.print("新年快乐!",COLOR.white) LOG.print("新年快乐!",COLOR.white)
LOG.print(" ★☆☆★",COLOR.red) LOG.print(" ★☆☆★",COLOR.red)
elseif theme=="zday"then elseif theme=="zday1"then
BG.setDefault("lanterns") BG.setDefault("lanterns")
BGM.setDefault("overzero") BGM.setDefault("overzero")
elseif theme=="zday2"then
BG.setDefault("lanterns")
BGM.setDefault("vacuum")
elseif theme=="fool"then elseif theme=="fool"then
BG.setDefault("blockrain") BG.setDefault("blockrain")
BGM.setDefault("how feeling") BGM.setDefault("how feeling")

View File

@@ -86,9 +86,9 @@ local _send do
local mask_key={1,14,5,14} local mask_key={1,14,5,14}
local mask_str=char(unpack(mask_key)) local mask_str=char(unpack(mask_key))
function _send(opcode,message) function _send(op,message)
--Message type --Message type
SOCK:send(char(bor(0x80,opcode))) SOCK:send(char(bor(0x80,op)))
if message then if message then
--Length --Length

View File

@@ -1,7 +1,7 @@
VERSION={ VERSION={
code=1403, code=1404,
string="Alpha V0.14.3", string="Alpha V0.14.4",
name="曙光 Morning Twilight", name="日出 Sunrise",
} }
function love.conf(t) function love.conf(t)
t.identity="Techmino"--Saving folder t.identity="Techmino"--Saving folder

View File

@@ -33,40 +33,24 @@ love.keyboard.setKeyRepeat(true)
love.keyboard.setTextInput(false) love.keyboard.setTextInput(false)
love.mouse.setVisible(false) love.mouse.setVisible(false)
--Delete all files from too old version
for _,name in next,fs.getDirectoryItems("")do
if fs.getRealDirectory(name)==SAVEDIR and fs.getInfo(name).type~="directory"then
fs.remove(name)
end
end
--Create directories --Create directories
for _,v in next,{"conf","record","replay","cache"}do for _,v in next,{"conf","record","replay","cache"}do
local info=fs.getInfo(v) local info=fs.getInfo(v)
if not info then if not info then
fs.createDirectory(v) fs.createDirectory(v)
elseif info.type ~= 'directory' then elseif info.type~="directory"then
fs.remove(v) fs.remove(v)
fs.createDirectory(v) fs.createDirectory(v)
end end
end end
--Collect files of old version
if fs.getInfo("data.dat")or fs.getInfo("key.dat")or fs.getInfo("settings.dat")then
for k,v in next,{
["settings.dat"]="conf/settings",
["unlock.dat"]="conf/unlock",
["data.dat"]="conf/data",
["key.dat"]="conf/key",
["virtualkey.dat"]="conf/virtualkey",
["account.dat"]="conf/user",
}do
if fs.getInfo(k)then
fs.write(v,fs.read(k))
fs.remove(k)
end
end
for _,name in next,fs.getDirectoryItems("")do
if name:sub(-4)==".dat"then
fs.write("record/"..name:sub(1,-4).."rec",fs.read(name))
fs.remove(name)
end
end
end
--Load modules --Load modules
require"Zframework" require"Zframework"
@@ -274,6 +258,7 @@ do
end end
if STAT.version<1400 then if STAT.version<1400 then
fs.remove("conf/user") fs.remove("conf/user")
fs.remove("conf/key")
SETTING.appLock=false SETTING.appLock=false
needSave=true needSave=true
autoRestart=true autoRestart=true
@@ -316,16 +301,6 @@ do
RANKS.sprint_10l=0 RANKS.sprint_10l=0
needSave=true needSave=true
end end
if needSave then
FILE.save(RANKS,"conf/unlock","q")
FILE.save(SETTING,"conf/settings","q")
end
if keyMap[1]then
autoRestart=true
fs.remove("conf/key")
end
USER.username=nil
if STAT.version~=VERSION.code then if STAT.version~=VERSION.code then
newVersionLaunch=true newVersionLaunch=true
@@ -333,6 +308,10 @@ do
FILE.save(STAT,"conf/data","q") FILE.save(STAT,"conf/data","q")
end end
if needSave then
FILE.save(RANKS,"conf/unlock","q")
FILE.save(SETTING,"conf/settings","q")
end
if autoRestart then if autoRestart then
love.event.quit("restart") love.event.quit("restart")
end end

BIN
media/BGM/super7th.ogg Normal file

Binary file not shown.

BIN
media/BGM/vacuum.ogg Normal file

Binary file not shown.

View File

@@ -276,6 +276,7 @@ SETTING={--Settings
fullscreen=true, fullscreen=true,
bg=true, bg=true,
powerInfo=false, powerInfo=false,
clickFX=true,
--Sound --Sound
sfx=1, sfx=1,

View File

@@ -259,7 +259,8 @@ return{
down="", down="",
}, },
net_game={ net_game={
ready="Ready/Cancel", ready="Ready",
cancel="Cancel",
}, },
net_chat={ net_chat={
send="Send", send="Send",
@@ -310,8 +311,9 @@ return{
highCam="Screen Scrolling", highCam="Screen Scrolling",
nextPos="Next Preview", nextPos="Next Preview",
fullscreen="Full Screen", fullscreen="Full Screen",
bg="Background",
power="Power Info", power="Power Info",
clickFX="Click FX",
bg="Background",
clean="Fast Draw", clean="Fast Draw",
}, },
setting_sound={ setting_sound={

View File

@@ -231,7 +231,8 @@ return{
down="", down="",
}, },
net_game={ net_game={
-- ready="Ready/Cancel", -- ready="Ready",
-- cancel="Cancel",
}, },
net_chat={ net_chat={
send="Envoyer", send="Envoyer",
@@ -284,8 +285,9 @@ return{
highCam="Vue d'oiseau", highCam="Vue d'oiseau",
nextPos="Prévisualisation de position", nextPos="Prévisualisation de position",
fullscreen="Plein écran", fullscreen="Plein écran",
bg="Arrière-plan",
power="Infos d'alimentation", power="Infos d'alimentation",
-- clickFX="Click FX",
bg="Arrière-plan",
-- clean="Fast Draw", -- clean="Fast Draw",
}, },
setting_sound={ setting_sound={

View File

@@ -259,7 +259,8 @@ return{
down="", down="",
}, },
net_game={ net_game={
-- ready="Ready/Cancel", -- ready="Ready",
-- cancel="Cancel",
}, },
net_chat={ net_chat={
send="Mandar", send="Mandar",
@@ -310,8 +311,9 @@ return{
highCam="Vista Olho-de-pássaro", highCam="Vista Olho-de-pássaro",
nextPos="Próxima Pos.", nextPos="Próxima Pos.",
fullscreen="Tela cheia", fullscreen="Tela cheia",
bg="Fundo",
power="Informação bateria", power="Informação bateria",
-- clickFX="Click FX",
bg="Fundo",
-- clean="Fast Draw", -- clean="Fast Draw",
}, },
setting_sound={ setting_sound={

View File

@@ -238,6 +238,7 @@ return{
}, },
net_game={ net_game={
ready="Estoy Listo", ready="Estoy Listo",
-- cancel="Cancel",
}, },
net_chat={ net_chat={
send="Enviar", send="Enviar",
@@ -288,8 +289,9 @@ return{
highCam="Cám. Vista Aérea", highCam="Cám. Vista Aérea",
nextPos="Ver Spawn de Pza. Sig.", nextPos="Ver Spawn de Pza. Sig.",
fullscreen="Pant. Completa", fullscreen="Pant. Completa",
bg="Fondo",
power="Inf. de Batería", power="Inf. de Batería",
-- clickFX="Click FX",
bg="Fondo",
clean="Fast Draw", clean="Fast Draw",
}, },
setting_sound={ setting_sound={

View File

@@ -169,8 +169,9 @@ return{
highCam="↑__↑", highCam="↑__↑",
nextPos="???←", nextPos="???←",
fullscreen="|←→|", fullscreen="|←→|",
bg="__?__",
power="+.", power="+.",
clickFX="_.~",
bg="__?__",
clean="[]→→O", clean="[]→→O",
}, },
setting_sound={ setting_sound={

View File

@@ -259,7 +259,8 @@ return{
down="", down="",
}, },
net_game={ net_game={
ready="准备/取消", ready="准备",
cancel="取消",
}, },
net_chat={ net_chat={
send="发送", send="发送",
@@ -310,8 +311,9 @@ return{
highCam="超屏视野", highCam="超屏视野",
nextPos="生成预览", nextPos="生成预览",
fullscreen="全屏", fullscreen="全屏",
bg="背景",
power="电量显示", power="电量显示",
clickFX="点按特效",
bg="背景",
clean="绘制优化", clean="绘制优化",
}, },
setting_sound={ setting_sound={

View File

@@ -6,7 +6,7 @@ return{
visible="easy", visible="easy",
dropPiece=function(P)if P.stat.row>=200 then P:win("finish")end end, dropPiece=function(P)if P.stat.row>=200 then P:win("finish")end end,
freshLimit=10, freshLimit=10,
bg="glow",bgm="reason", bg="glow",bgm="push",
}, },
pauseLimit=true, pauseLimit=true,
load=function() load=function()

View File

@@ -10,7 +10,7 @@ return{
score=false, score=false,
dropPiece=function(P)if P.stat.row>=200 then P:win("finish")end end, dropPiece=function(P)if P.stat.row>=200 then P:win("finish")end end,
freshLimit=15, freshLimit=15,
bg="rgb",bgm="reason", bg="rgb",bgm="push",
}, },
pauseLimit=true, pauseLimit=true,
load=function() load=function()

View File

@@ -11,7 +11,7 @@ return{
score=false, score=false,
dropPiece=function(P)if P.stat.row>=200 then P:win("finish")end end, dropPiece=function(P)if P.stat.row>=200 then P:win("finish")end end,
freshLimit=15, freshLimit=15,
bg="rgb",bgm="reason", bg="rgb",bgm="push",
}, },
pauseLimit=true, pauseLimit=true,
load=function() load=function()

View File

@@ -7,7 +7,7 @@ return{
freshLimit=10, freshLimit=10,
visible="fast", visible="fast",
dropPiece=function(P)if P.stat.row>=200 then P:win("finish")end end, dropPiece=function(P)if P.stat.row>=200 then P:win("finish")end end,
bg="glow",bgm="reason", bg="glow",bgm="push",
}, },
pauseLimit=true, pauseLimit=true,
load=function() load=function()

View File

@@ -10,7 +10,7 @@ return{
score=false, score=false,
dropPiece=function(P)if P.stat.row>=100 then P:win("finish")end end, dropPiece=function(P)if P.stat.row>=100 then P:win("finish")end end,
freshLimit=15, freshLimit=15,
bg="rgb",bgm="push", bg="rgb",bgm="far",
}, },
pauseLimit=true, pauseLimit=true,
load=function() load=function()

View File

@@ -10,7 +10,7 @@ return{
visible="none", visible="none",
dropPiece=function(P)if P.stat.row>=40 then P:win("finish")end end, dropPiece=function(P)if P.stat.row>=40 then P:win("finish")end end,
freshLimit=15, freshLimit=15,
bg="none",bgm="push", bg="none",bgm="far",
}, },
pauseLimit=true, pauseLimit=true,
load=function() load=function()

View File

@@ -14,7 +14,7 @@ return{
local p=P.modeData.pt+P.lastPiece.row local p=P.modeData.pt+P.lastPiece.row
if p>=P.modeData.target then if p>=P.modeData.target then
local ENV=P.gameEnv local ENV=P.gameEnv
local T=ENV.target local T=P.modeData.target
--Stage 1: clear 3 techrash --Stage 1: clear 3 techrash
if T==12 then--Stage 2: swap color of S/Z & J/L if T==12 then--Stage 2: swap color of S/Z & J/L
P.waiting=30 P.waiting=30
@@ -28,7 +28,7 @@ return{
ENV.fall=7 ENV.fall=7
P:setNext(4) P:setNext(4)
ENV.target=26 P.modeData.target=26
SFX.play("reach") SFX.play("reach")
elseif T==26 then--Stage 3: dig to bottom elseif T==26 then--Stage 3: dig to bottom
if not P.holdQueue[1]then P.life=P.life+1 end--1 up if ban hold if not P.holdQueue[1]then P.life=P.life+1 end--1 up if ban hold
@@ -70,7 +70,7 @@ return{
ENV.fall=6 ENV.fall=6
P:setNext(5) P:setNext(5)
ENV.target=42 P.modeData.target=42
SFX.play("reach") SFX.play("reach")
elseif T==42 then--Stage 4: survive in high speed elseif T==42 then--Stage 4: survive in high speed
if P.garbageBeneath==0 then if P.garbageBeneath==0 then
@@ -80,7 +80,7 @@ return{
P:setHold(false) P:setHold(false)
ENV.bone=true ENV.bone=true
ENV.target=62 P.modeData.target=62
else else
p=41 p=41
end end
@@ -92,7 +92,7 @@ return{
ENV.easyFresh=false ENV.easyFresh=false
ENV.target=126 P.modeData.target=126
SFX.play("reach") SFX.play("reach")
elseif T==126 then--Stage 6: speed up elseif T==126 then--Stage 6: speed up
P.life=P.life+1 P.life=P.life+1
@@ -101,7 +101,7 @@ return{
ENV.wait=4 ENV.wait=4
ENV.fall=4 ENV.fall=4
ENV.target=162 P.modeData.target=162
elseif T==162 then--Stage 7: speed up+++ elseif T==162 then--Stage 7: speed up+++
P.life=P.life+1 P.life=P.life+1
@@ -110,7 +110,7 @@ return{
P:setHold(true) P:setHold(true)
P:setInvisible(180) P:setInvisible(180)
ENV.target=226 P.modeData.target=226
SFX.play("reach") SFX.play("reach")
elseif T==226 then--Stage 8: final invisible elseif T==226 then--Stage 8: final invisible
P.life=P.life+2 P.life=P.life+2
@@ -118,7 +118,7 @@ return{
ENV.bone=false ENV.bone=false
P:setInvisible(90) P:setInvisible(90)
ENV.target=259 P.modeData.target=259
SFX.play("reach") SFX.play("reach")
elseif T==259 then--Stage 9: ending elseif T==259 then--Stage 9: ending
P.life=P.life+1 P.life=P.life+1
@@ -130,7 +130,7 @@ return{
ENV.mission={4,4,4,4,4,4,4,4} ENV.mission={4,4,4,4,4,4,4,4}
ENV.missionKill=false ENV.missionKill=false
ENV.target=260 P.modeData.target=260
p=260 p=260
SFX.play("blip_2") SFX.play("blip_2")
else else
@@ -142,7 +142,7 @@ return{
mission={4,4,4,64}, mission={4,4,4,64},
missionKill=true, missionKill=true,
freshLimit=12, freshLimit=12,
bg="none",bgm="distortion", bg="none",bgm="super7th",
}, },
slowMark=true, slowMark=true,
load=function() load=function()

View File

@@ -134,7 +134,7 @@ function NET.register(username,email,password)
end end
end end
function NET.pong(wsName,message) function NET.pong(wsName,message)
WS.send(wsName,message,"pong") WS.send(wsName,type(message)=="string"and message or"","pong")
end end
function NET.getAccessToken() function NET.getAccessToken()
if NET.lock("access_and_login",10)then if NET.lock("access_and_login",10)then
@@ -385,7 +385,7 @@ function NET.updateWS_play()
ready=d.ready, ready=d.ready,
config=d.config, config=d.config,
}) })
SCN.socketRead("Join",d) if SCN.socketRead then SCN.socketRead("Join",d)end
end end
elseif res.action==3 then--Player leave elseif res.action==3 then--Player leave
if not d.uid then if not d.uid then
@@ -411,10 +411,10 @@ function NET.updateWS_play()
break break
end end
end end
SCN.socketRead("Leave",d) if SCN.socketRead then SCN.socketRead("Leave",d)end
end end
elseif res.action==4 then--Player talk elseif res.action==4 then--Player talk
SCN.socketRead("Talk",d) 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
if tostring(USER.uid)~=d.uid then if tostring(USER.uid)~=d.uid then
for i=1,#PLY_NET do for i=1,#PLY_NET do
@@ -434,12 +434,12 @@ function NET.updateWS_play()
SFX.play("spin_0",.6) SFX.play("spin_0",.6)
if i==1 then if i==1 then
NET.unlock("ready") NET.unlock("ready")
else elseif not PLY_NET[1].ready then
for j=2,#PLY_NET do for j=2,#PLY_NET do
if not PLY_NET[j].ready then if not PLY_NET[j].ready then
break break
elseif j==#PLY_NET then elseif j==#PLY_NET then
SFX.play("warning",.5) SFX.play("blip_2",.5)
end end
end end
end end
@@ -454,8 +454,8 @@ function NET.updateWS_play()
NET.wsconn_stream() NET.wsconn_stream()
TASK.new(NET.updateWS_stream) TASK.new(NET.updateWS_stream)
elseif res.action==9 then--Game finished elseif res.action==9 then--Game finished
SCN.socketRead("Finish",d)
NET.wsclose_stream() NET.wsclose_stream()
if SCN.socketRead then SCN.socketRead("Finish",d)end
end end
else else
WS.alert("play") WS.alert("play")
@@ -493,7 +493,13 @@ function NET.updateWS_stream()
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
--? local uid=res.data.uid
for _,P in next,PLY_ALIVE do
if P.uid==uid then
P:lose(true)
break
end
end
elseif res.action==5 then--Receive stream elseif res.action==5 then--Receive stream
SCN.socketRead("Stream",d) SCN.socketRead("Stream",d)
end end

View File

@@ -20,6 +20,7 @@ local seqGens={
end, end,
his4=function(P,seq0) his4=function(P,seq0)
local len=#seq0 local len=#seq0
local his={0,0,0,0}
while true do while true do
while #P.nextQueue<6 do while #P.nextQueue<6 do
for n=1,4 do for n=1,4 do
@@ -27,8 +28,8 @@ local seqGens={
repeat repeat
i=seq0[P:RND(len)] i=seq0[P:RND(len)]
j=j+1 j=j+1
until i~=seq0[1]and i~=seq0[2]and i~=seq0[3]and i~=seq0[4]or j==4 until i~=his[1]and i~=his[2]and i~=his[3]and i~=his[4]or j==4
seq0[n]=i his[n]=i
P:getNext(i) P:getNext(i)
end end
end end

View File

@@ -643,7 +643,8 @@ function Player:hold(ifpre)
local ENV=self.gameEnv local ENV=self.gameEnv
if self.holdTime>0 and(ifpre or self.waiting==-1)then if self.holdTime>0 and(ifpre or self.waiting==-1)then
if #self.holdQueue<ENV.holdCount and self.nextQueue[1]then--Skip if #self.holdQueue<ENV.holdCount and self.nextQueue[1]then--Skip
ins(self.holdQueue,self:getBlock(self.cur.id)) local C=self.cur
ins(self.holdQueue,self:getBlock(C.id,C.name,C.color))
local t=self.holdTime local t=self.holdTime
self:popNext(true) self:popNext(true)
@@ -730,16 +731,16 @@ function Player:hold(ifpre)
end end
end end
function Player:getBlock(n)--Get a block(id=n) object function Player:getBlock(id,name,color)--Get a block(id=n) object
local E=self.gameEnv local E=self.gameEnv
local dir=E.face[n] local dir=E.face[id]
return{ return{
id=n, id=id,
bk=BLOCKS[n][dir],
sc=SCS[n][dir],
dir=dir, dir=dir,
name=n, bk=BLOCKS[id][dir],
color=E.bone and 17 or E.skin[n], sc=SCS[id][dir],
name=name or id,
color=E.bone and 17 or color or E.skin[id],
} }
end end
function Player:getNext(n)--Push a block(id=n) to nextQueue function Player:getNext(n)--Push a block(id=n) to nextQueue
@@ -1723,6 +1724,7 @@ function Player:win(result)
end end
function Player:lose(force) function Player:lose(force)
if self.result then return end if self.result then return end
if self.type=="remote"and not force then self.waiting=1e99 return end
if self.life>0 and not force then if self.life>0 and not force then
self.waiting=62 self.waiting=62
local h=#self.field local h=#self.field

View File

@@ -293,14 +293,11 @@ function scene.draw()
for j=1,4 do for j=1,4 do
if cx~=j or cy~=i then if cx~=j or cy~=i then
local N=board[i][j] local N=board[i][j]
local C=mono and 3 or color
local C=mono and 1 or color gc.setColor(backColor[C][N])
local back=backColor[C]
local front=frontColor[C]
gc.setColor(back[N])
gc.rectangle("fill",j*160+163,i*160-117,154,154,8) gc.rectangle("fill",j*160+163,i*160-117,154,154,8)
gc.setColor(front[N]) gc.setColor(frontColor[C][N])
gc.rectangle("line",j*160+163,i*160-117,154,154,8) gc.rectangle("line",j*160+163,i*160-117,154,154,8)
if not mono then if not mono then
gc.setColor(.1,.1,.1) gc.setColor(.1,.1,.1)

View File

@@ -128,33 +128,34 @@ local function squash(L)
local moved=false local moved=false
while true do while true do
p2=p1+1 p2=p1+1
while not L[p2]do while not L[p2]and p2<5 do
p2=p2+1 p2=p2+1
if p2==5 then
p1=p1+1
if p1==4 then
return L[1],L[2],L[3],L[4],moved
end
break
end
end end
if not L[p1]then--air←2 if p2==5 then
L[p1],L[p2]=L[p2],false if p1==4 then
moved=true return L[1],L[2],L[3],L[4],moved
elseif L[p1]==L[p2]then--2←2 else
L[p1],L[p2]=L[p1]+1,false p1=p1+1
if L[p1]>maxTile then end
freshMaxTile() else
if not L[p1]then--air←2
L[p1],L[p2]=L[p2],false
moved=true
elseif L[p1]==L[p2]then--2←2
L[p1],L[p2]=L[p1]+1,false
if L[p1]>maxTile then
freshMaxTile()
end
L[p2]=false
p1=p1+1
moved=true
elseif p1+1~=p2 then--2←4
L[p1+1],L[p2]=L[p2],false
p1=p1+1
moved=true
else--2,4
p1=p1+1
end end
L[p2]=false
p1=p1+1
moved=true
elseif p1+1~=p2 then--2←4
L[p1+1],L[p2]=L[p2],false
p1=p1+1
moved=true
else--2,4
p1=p1+1
end end
end end
end end

View File

@@ -196,7 +196,7 @@ do--commands.help(arg)
details={ details={
"Set background.", "Set background.",
"", "",
"Usage: setbg <classic|xmas|sprfes|zday>", "Usage: setbg <classic|xmas|sprfes|zday1|zday2>",
}, },
}, },
theme={ theme={
@@ -204,7 +204,7 @@ do--commands.help(arg)
details={ details={
"Load a theme.", "Load a theme.",
"", "",
"Usage: theme <classic|xmas|sprfes|zday>", "Usage: theme <classic|xmas|sprfes|zday1|zday2>",
}, },
}, },
demo={ demo={
@@ -488,7 +488,7 @@ function commands.demo()
SCN.go("test","none") SCN.go("test","none")
end end
do--commands.applet(name) do--commands.applet(name)
local appList={"15p","grid","pong","atoz","uttt","cube","2048","ten","tap","dtw","cannon","drppper","calc","reflect","polyforge"} local appList={"15p","grid","pong","atoz","uttt","cube","2048","ten","tap","dtw","cannon","drp","calc","reflect","polyforge"}
local appScene={"app_15p","app_schulteG","app_pong","app_AtoZ","app_UTTT","app_cubefield","app_2048","app_ten","app_tap","app_dtw","app_cannon","app_dropper","app_calc","app_reflect","app_polyforge"} local appScene={"app_15p","app_schulteG","app_pong","app_AtoZ","app_UTTT","app_cubefield","app_2048","app_ten","app_tap","app_dtw","app_cannon","app_dropper","app_calc","app_reflect","app_polyforge"}
function commands.applet(name) function commands.applet(name)
if name=="-list"then if name=="-list"then

View File

@@ -104,7 +104,7 @@ end
function scene.sceneInit() function scene.sceneInit()
sure=0 sure=0
penColor=1 penColor=-2
penMode=false penMode=false
penX,penY=1,1 penX,penY=1,1
demo=false demo=false

View File

@@ -34,6 +34,7 @@ function scene.sceneInit()
upstreamProgress=1 upstreamProgress=1
end end
scene.mouseDown=NULL
function scene.touchDown(x,y) function scene.touchDown(x,y)
if noTouch or not playing then return end if noTouch or not playing then return end
@@ -274,6 +275,14 @@ scene.widgetList={
return return
playing or playing or
not textBox.hide or not textBox.hide or
PLY_NET[1].ready or
NET.getlock("ready")
end},
WIDGET.newKey{name="cancel",x=900,y=560,w=400,h=100,color="grey",font=40,code=pressKey"space",hide=function()
return
playing or
not textBox.hide or
not PLY_NET[1].ready or
NET.getlock("ready") NET.getlock("ready")
end}, end},
WIDGET.newKey{name="hideChat",fText="...",x=380,y=35,w=60,font=35,code=pressKey"\\"}, WIDGET.newKey{name="hideChat",fText="...",x=380,y=35,w=60,font=35,code=pressKey"\\"},

View File

@@ -1,5 +1,16 @@
local scene={} local scene={}
local function legalEmail(e)
e=SPLITSTR(e,"@")
if #e~=2 then return false end
if e[1]:sub(-1)=="."or e[2]:sub(-1)=="."then return false end
local e1,e2=SPLITSTR(e[1],"."),SPLITSTR(e[2],".")
if #e1*#e2==0 then return false end
for _,v in next,e1 do if #v==0 then return false end end
for _,v in next,e2 do if #v==0 then return false end end
return true
end
local function register() local function register()
local username= WIDGET.active.username.value local username= WIDGET.active.username.value
local email= WIDGET.active.email.value local email= WIDGET.active.email.value
@@ -7,7 +18,7 @@ local function register()
local password2=WIDGET.active.password2.value local password2=WIDGET.active.password2.value
if #username==0 then if #username==0 then
LOG.print(text.noUsername)return LOG.print(text.noUsername)return
elseif not email:match("^[a-zA-Z0-9_]+@[a-zA-Z0-9_-]+%.[a-zA-Z0-9_]+$")then elseif not legalEmail(email)then
LOG.print(text.wrongEmail)return LOG.print(text.wrongEmail)return
elseif #password==0 or #password2==0 then elseif #password==0 or #password2==0 then
LOG.print(text.noPassword)return LOG.print(text.noPassword)return

View File

@@ -13,22 +13,22 @@ scene.widgetList={
WIDGET.newButton{name="sound", x=200, y=80,w=240,h=80,color="lCyan",font=35,code=swapScene"setting_sound","swipeR"}, WIDGET.newButton{name="sound", x=200, y=80,w=240,h=80,color="lCyan",font=35,code=swapScene"setting_sound","swipeR"},
WIDGET.newButton{name="game", x=1080, y=80,w=240,h=80,color="lCyan",font=35,code=swapScene"setting_game","swipeL"}, WIDGET.newButton{name="game", x=1080, y=80,w=240,h=80,color="lCyan",font=35,code=swapScene"setting_game","swipeL"},
WIDGET.newSwitch{name="block", x=340, y=150, disp=SETval("block"), code=SETrev("block")}, WIDGET.newSwitch{name="block", x=290, y=165, disp=SETval("block"), code=SETrev("block")},
WIDGET.newSwitch{name="smooth", x=340, y=210, disp=SETval("smooth"), code=SETrev("smooth")}, WIDGET.newSwitch{name="smooth", x=290, y=215, disp=SETval("smooth"), code=SETrev("smooth")},
WIDGET.newSwitch{name="upEdge", x=340, y=270, disp=SETval("upEdge"), code=SETrev("upEdge")}, WIDGET.newSwitch{name="upEdge", x=290, y=265, disp=SETval("upEdge"), code=SETrev("upEdge")},
WIDGET.newSwitch{name="bagLine", x=340, y=330, disp=SETval("bagLine"), code=SETrev("bagLine")}, WIDGET.newSwitch{name="bagLine", x=290, y=315, disp=SETval("bagLine"), code=SETrev("bagLine")},
WIDGET.newSlider{name="ghost", x=630, y=180,w=200,unit=.6,disp=SETval("ghost"),show="percent",code=SETsto("ghost")}, WIDGET.newSlider{name="ghost", x=600, y=180,w=200,unit=.6,disp=SETval("ghost"),show="percent",code=SETsto("ghost")},
WIDGET.newSlider{name="grid", x=630, y=240,w=200,unit=.4,disp=SETval("grid"),show="percent", code=SETsto("grid")}, WIDGET.newSlider{name="grid", x=600, y=240,w=200,unit=.4,disp=SETval("grid"),show="percent", code=SETsto("grid")},
WIDGET.newSlider{name="center", x=630, y=300,w=200,unit=1, disp=SETval("center"), code=SETsto("center")}, WIDGET.newSlider{name="center", x=600, y=300,w=200,unit=1, disp=SETval("center"), code=SETsto("center")},
WIDGET.newSlider{name="lockFX", x=350, y=375,w=373,unit=5, disp=SETval("lockFX"), code=SETsto("lockFX")}, WIDGET.newSlider{name="lockFX", x=250, y=375,w=373,unit=5, disp=SETval("lockFX"), code=SETsto("lockFX")},
WIDGET.newSlider{name="dropFX", x=350, y=420,w=373,unit=5, disp=SETval("dropFX"), code=SETsto("dropFX")}, WIDGET.newSlider{name="dropFX", x=250, y=420,w=373,unit=5, disp=SETval("dropFX"), code=SETsto("dropFX")},
WIDGET.newSlider{name="moveFX", x=350, y=465,w=373,unit=5, disp=SETval("moveFX"), code=SETsto("moveFX")}, WIDGET.newSlider{name="moveFX", x=250, y=465,w=373,unit=5, disp=SETval("moveFX"), code=SETsto("moveFX")},
WIDGET.newSlider{name="clearFX", x=350, y=510,w=373,unit=5, disp=SETval("clearFX"), code=SETsto("clearFX")}, WIDGET.newSlider{name="clearFX", x=250, y=510,w=373,unit=5, disp=SETval("clearFX"), code=SETsto("clearFX")},
WIDGET.newSlider{name="splashFX", x=350, y=555,w=373,unit=5, disp=SETval("splashFX"),code=SETsto("splashFX")}, WIDGET.newSlider{name="splashFX", x=250, y=555,w=373,unit=5, disp=SETval("splashFX"),code=SETsto("splashFX")},
WIDGET.newSlider{name="shakeFX", x=350, y=600,w=373,unit=5, disp=SETval("shakeFX"), code=SETsto("shakeFX")}, WIDGET.newSlider{name="shakeFX", x=250, y=600,w=373,unit=5, disp=SETval("shakeFX"), code=SETsto("shakeFX")},
WIDGET.newSlider{name="atkFX", x=350, y=645,w=373,unit=5, disp=SETval("atkFX"), code=SETsto("atkFX")}, WIDGET.newSlider{name="atkFX", x=250, y=645,w=373,unit=5, disp=SETval("atkFX"), code=SETsto("atkFX")},
WIDGET.newSlider{name="frame", x=350, y=690,w=373,unit=10, WIDGET.newSlider{name="frame", x=350, y=690,w=373,unit=10,
disp=function() disp=function()
return SETTING.frameMul>35 and SETTING.frameMul/10 or SETTING.frameMul/5-4 return SETTING.frameMul>35 and SETTING.frameMul/10 or SETTING.frameMul/5-4
@@ -37,20 +37,21 @@ scene.widgetList={
SETTING.frameMul=i<5 and 5*i+20 or 10*i SETTING.frameMul=i<5 and 5*i+20 or 10*i
end}, end},
WIDGET.newSwitch{name="text", x=1100, y=180,font=35,disp=SETval("text"), code=SETrev("text")}, WIDGET.newSwitch{name="text", x=1140, y=160,font=35,disp=SETval("text"), code=SETrev("text")},
WIDGET.newSwitch{name="score", x=1100, y=240,font=35,disp=SETval("score"), code=SETrev("score")}, WIDGET.newSwitch{name="score", x=1140, y=210,font=35,disp=SETval("score"), code=SETrev("score")},
WIDGET.newSwitch{name="warn", x=1100, y=300,font=35,disp=SETval("warn"), code=SETrev("warn")}, WIDGET.newSwitch{name="warn", x=1140, y=260,font=35,disp=SETval("warn"), code=SETrev("warn")},
WIDGET.newSwitch{name="highCam", x=1100, y=360,font=35,disp=SETval("highCam"),code=SETrev("highCam")}, WIDGET.newSwitch{name="highCam", x=1140, y=310,font=35,disp=SETval("highCam"),code=SETrev("highCam")},
WIDGET.newSwitch{name="nextPos", x=1100, y=420,font=35,disp=SETval("nextPos"),code=SETrev("nextPos")}, WIDGET.newSwitch{name="nextPos", x=1140, y=360,font=35,disp=SETval("nextPos"),code=SETrev("nextPos")},
WIDGET.newSwitch{name="fullscreen",x=1100, y=480,disp=SETval("fullscreen"), code=switchFullscreen}, WIDGET.newSwitch{name="fullscreen", x=1140, y=410,disp=SETval("fullscreen"), code=switchFullscreen},
WIDGET.newSwitch{name="bg", x=1100, y=540,font=35,disp=SETval("bg"), WIDGET.newSwitch{name="power", x=1140, y=460,font=35,disp=SETval("powerInfo"),code=SETrev("powerInfo")},
WIDGET.newSwitch{name="clickFX", x=1140, y=510,font=35,disp=SETval("clickFX"),code=SETrev("clickFX")},
WIDGET.newSwitch{name="bg", x=1140, y=560,font=35,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="power", x=990, y=610,font=35,disp=SETval("powerInfo"),code=SETrev("powerInfo")}, WIDGET.newSwitch{name="clean", x=990, y=640,font=35,disp=SETval("cleanCanvas"),code=SETrev("cleanCanvas")},
WIDGET.newSwitch{name="clean", x=990, y=670,font=35,disp=SETval("cleanCanvas"),code=SETrev("cleanCanvas")},
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

@@ -22,6 +22,29 @@ return SPLITSTR([=[
可选虚拟按键颜色; 工程编译到字节码; task-Z(新AI) 可选虚拟按键颜色; 工程编译到字节码; task-Z(新AI)
录像回放菜单; 跳帧开关; 教学关; 超60帧; 热更新 录像回放菜单; 跳帧开关; 教学关; 超60帧; 热更新
0.14.4: 日出 Sunrise
新增:
添加触摸/点击特效开关
新增BGM:super7th(用于master-ph模式)
新增BGM:vacuum(用于节日主题)
改动:
自定义场地默认使用智能画笔
对战房间的准备按钮颜色和文本会随状态改变
联网对战时禁用鼠标右键返回
添加触摸/点击特效开关
修改隐形模式BGM配置
更换催促等待提示音
不再接受过老版本的存档
修复:
玩家死亡消息以服务器为准,录像不同步不再影响结算
O块在变形后hold失去名字和颜色属性
master-ph错误
注册时部分合法邮箱格式会被判错
his序列模式算法错误
小程序2048出新格的逻辑错误
小程序15p盲打颜色配置错误
一个小程序入口名错误
0.14.3: 曙光 Morning Twilight 0.14.3: 曙光 Morning Twilight
改动: 改动:
尝试进联网菜单的两步都完成前再次点击按钮无效 尝试进联网菜单的两步都完成前再次点击按钮无效