升级录像格式,完善录像回放菜单

This commit is contained in:
MrZ626
2021-06-28 02:43:47 +08:00
parent 6cb81b461b
commit b0ecb28b48
7 changed files with 136 additions and 105 deletions

View File

@@ -1,4 +1,5 @@
local loveCompress=love.data.compress
local loveDecompress=love.data.decompress
local int=math.floor
local char,byte=string.char,string.byte
@@ -336,7 +337,7 @@ function DATA.pumpRecording(str,L)
p=p+1
end
end
do--function DATA.saveRecording()
do--function DATA.saveReplay()
local noRecList={"custom","solo","round","techmino"}
local function getModList()
local res={}
@@ -347,7 +348,7 @@ do--function DATA.saveRecording()
end
return res
end
function DATA.saveRecording()
function DATA.saveReplay()
--Filtering modes that cannot be saved
for _,v in next,noRecList do
if GAME.curModeName:find(v)then
@@ -357,27 +358,59 @@ do--function DATA.saveRecording()
end
--Write file
local fileName=os.date("replay/%Y_%m_%d_%a_%H%M%S.rep")
local fileName=os.date("replay/%Y_%m_%d_%H%M%S.rep")
if not love.filesystem.getInfo(fileName)then
local fileHead=
os.date("%Y/%m/%d %A %H:%M:%S\n")..
GAME.curModeName.."\n"..
VERSION.string.."\n"..
USERS.getUsername(USER.uid).."\n"
local fileBody=
GAME.seed.."\n"..
JSON.encode(GAME.setting).."\n"..
JSON.encode(getModList()).."\n"..
DATA.dumpRecording(GAME.rep)
love.filesystem.write(fileName,fileHead..loveCompress('string','zlib',fileBody))
ins(REPLAY,fileName)
FILE.save(REPLAY,'conf/replay')
love.filesystem.write(fileName,
loveCompress('string','zlib',
JSON.encode{
date=os.date("%Y/%m/%d %H:%M:%S"),
mode=GAME.curModeName,
version=VERSION.string,
player=USERS.getUsername(USER.uid),
seed=GAME.seed,
setting=GAME.setting,
mod=getModList(),
}.."\n"..
DATA.dumpRecording(GAME.rep)
)
)
ins(REPLAY,1,DATA.parseReplay(fileName))
return true
else
MES.new('error',"Save failed: File already exists")
end
end
end
function DATA.parseReplay(fileName,ifFull)
local fileData=love.filesystem.read(fileName)
if fileData and #fileData>0 then
fileData=loveDecompress('string','zlib',fileData)
local metaData
metaData,fileData=STRING.readLine(fileData)
metaData=JSON.decode(metaData)
local rep={
fileName=fileName,
available=true,
date=metaData.date,
mode=metaData.mode,
version=metaData.version,
player=metaData.player,
seed=metaData.seed,
setting=metaData.setting,
mod=metaData.mod,
modeName=("%s %s"):format(text.modes[metaData.mode][1],text.modes[metaData.mode][2]),
}
if ifFull then rep.data=fileData end
return rep
else
return{
fileName=fileName,
available=false,
}
end
end
return DATA

View File

@@ -228,10 +228,11 @@ function loadGame(mode,ifQuickPlay,ifNet)--Load a mode and go to game scene
freshDate()
if legalGameTime()then
if MODES[mode].score then STAT.lastPlay=mode end
GAME.init=true
GAME.fromRepMenu=false
GAME.curModeName=mode
GAME.curMode=MODES[mode]
GAME.modeEnv=GAME.curMode.env
GAME.init=true
GAME.net=ifNet
if ifNet then
SCN.go('net_game','swipeD')

View File

@@ -417,4 +417,4 @@ VK_org=FILE.load('conf/virtualkey')or{--Virtualkey layout, refresh all VKs' posi
{ava=false, x=900, y=50, r=80},--addToLeft
{ava=false, x=1000, y=50, r=80},--addToRight
}
REPLAY=FILE.load('conf/replay')or{}
REPLAY={}--Replay objects (not include stream data)

View File

@@ -130,11 +130,15 @@ function scene.keyDown(key,isRep)
elseif key=="escape"then
SCN.swapTo(GAME.result and'game'or'depause','none')
elseif key=="s"then
GAME.prevBG=BG.cur
SCN.go('setting_sound')
if not GAME.fromRepMenu then
GAME.prevBG=BG.cur
SCN.go('setting_sound')
end
elseif key=="r"then
resetGameData()
SCN.swapTo('game','none')
if not GAME.fromRepMenu then
resetGameData()
SCN.swapTo('game','none')
end
elseif key=="p"then
if(GAME.result or GAME.replaying)and #PLAYERS==1 then
resetGameData('r')
@@ -142,8 +146,9 @@ function scene.keyDown(key,isRep)
end
elseif key=="o"then
if(GAME.result or GAME.replaying)and #PLAYERS==1 and not GAME.saved then
if DATA.saveRecording()then
if DATA.saveReplay()then
GAME.saved=true
SFX.play('connected')
end
end
else
@@ -308,11 +313,11 @@ function scene.draw()
end
scene.widgetList={
WIDGET.newButton{name="setting", x=1120,y=70,w=240,h=90, color='lB',code=pressKey"s"},
WIDGET.newButton{name="setting", x=1120,y=70,w=240,h=90, color='lB',code=pressKey"s",hideF=function()return GAME.fromRepMenu end},
WIDGET.newButton{name="replay", x=535,y=250,w=200,h=100,color='lY',code=pressKey"p",hideF=function()return not(GAME.result or GAME.replaying)or #PLAYERS>1 end},
WIDGET.newButton{name="save", x=745,y=250,w=200,h=100,color='lP',code=pressKey"o",hideF=function()return not(GAME.result or GAME.replaying)or #PLAYERS>1 or GAME.saved end},
WIDGET.newButton{name="resume", x=640,y=367,w=240,h=100,color='lG',code=pressKey"escape"},
WIDGET.newButton{name="restart", x=640,y=483,w=240,h=100,color='lR',code=pressKey"r"},
WIDGET.newButton{name="restart", x=640,y=483,w=240,h=100,color='lR',code=pressKey"r",hideF=function()return GAME.fromRepMenu end},
WIDGET.newButton{name="quit", x=640,y=600,w=240,h=100,font=35,code=backScene},
}

View File

@@ -17,7 +17,7 @@ local listBox=WIDGET.newListBox{name="list",x=50,y=50,w=1200,h=520,lineH=40,draw
if rep.available then
gc_setColor(.9,.9,1)
gc_print(rep.modeName,405,-2)
gc_print(rep.modeName,310,-2)
setFont(20)
gc_setColor(1,1,.8)
gc_print(rep.date,80,6)
@@ -35,33 +35,22 @@ local scene={}
local sure
local function readLine(str)
local p=str:find("\n")
return str:sub(1,p-1),str:sub(p+1)
end
local function replay(rep)
local function replay(fileName)
local rep=DATA.parseReplay(fileName,true)
if not rep.available then
MES.new('error',text.replayBroken)
elseif MODES[rep.mode]then
local data=love.data.decompress('string','zlib',rep.data)
local seed,setting,mod
seed,data=readLine(data)
GAME.seed=tonumber(seed)
setting,data=readLine(data)
GAME.setting=JSON.decode(setting)
mod,data=readLine(data)
GAME.mod=JSON.decode(mod)
GAME.seed=rep.seed
GAME.setting=rep.setting
GAME.mod=rep.mod
GAME.rep={}
DATA.pumpRecording(data,GAME.rep)
DATA.pumpRecording(rep.data,GAME.rep)
loadGame(rep.mode,true)
resetGameData('r')
GAME.init=false
GAME.saved=true
GAME.fromRepMenu=true
else
MES.new('error',("No mode id: [%s]"):format(rep.mode))
end
@@ -69,73 +58,34 @@ end
function scene.sceneInit()
sure=0
local repList={}
for i=#REPLAY,1,-1 do
local file=love.filesystem.newFile(REPLAY[i])
if file:open('r')then
local metadata=""
local enter=0
while true do
local b,len=file:read(1)
if len==0 then
repList[i]={
fileName=REPLAY[i],
available=false,
}
break
end
metadata=metadata..b
if b=="\n"then
enter=enter+1
if enter==4 then
metadata=STRING.split(metadata,'\n')
local mode=text.modes[metadata[2]]or{"["..metadata[2].."]",""}
repList[i]={
fileName=REPLAY[i],
available=true,
date=metadata[1],
mode=metadata[2],
modeName=("%s %s"):format(mode[1],mode[2]),
version=metadata[3],
player=metadata[4],
data=file:read(),
}
break
end
end
end
file:close()
else
repList[i]={
fileName=REPLAY[i],
available=false,
}
end
end
listBox:setList(repList)
listBox:setList(REPLAY)
end
function scene.keyDown(key)
if key=="return"then
replay(listBox:getSel())
local rep=listBox:getSel()
if rep then
replay(rep.fileName)
end
elseif key=="escape"then
SCN.back()
elseif key=="delete"then
if sure>20 then
local rep=listBox:getSel()
if rep then
local rep=listBox:getSel()
if rep then
if sure>20 then
sure=0
listBox:remove()
love.filesystem.remove(rep.fileName)
local i=TABLE.find(REPLAY,rep.fileName)
if i then table.remove(REPLAY,i)end
FILE.save(REPLAY,'conf/replay')
for i=1,#REPLAY do
if REPLAY[i].fileName==rep.fileName then
table.remove(REPLAY,i)
break
end
end
SFX.play('finesseError',.7)
else
sure=50
end
else
sure=50
end
else
WIDGET.keyPressed(key)
@@ -159,6 +109,7 @@ scene.widgetList={
WIDGET.newButton{name="play",x=700,y=640,w=170,h=80,color='lY',code=pressKey"return",hideF=function()return listBox:getLen()==0 end,fText=DOGC{50,50,{'fPoly',10,0,49,24,10,49}}},
WIDGET.newButton{name="delete",x=850,y=640,w=80,h=80,color='lR',code=pressKey"delete",hideF=function()return listBox:getLen()==0 end,fText=DOGC{50,50,{'setLW',8},{'line',5,5,45,45},{'line',5,45,45,5}}},
WIDGET.newButton{name="back",x=1140,y=640,w=170,h=80,fText=TEXTURE.back,code=backScene},
WIDGET.newButton{name="back",x=1140,y=640,w=170,h=80,fText=TEXTURE.back,code=backScene},
}
return scene