新增virtualKey模块整理虚拟按键相关代码,整理代码

This commit is contained in:
MrZ626
2021-04-22 15:15:31 +08:00
parent 2400325b22
commit 9f956f965a
11 changed files with 359 additions and 341 deletions

View File

@@ -1,12 +1,7 @@
local data=love.data
local gc=love.graphics
local gc_setColor,gc_setLineWidth,gc_setShader=gc.setColor,gc.setLineWidth,gc.setShader
local gc_push,gc_pop,gc_origin,gc_translate=gc.push,gc.pop,gc.origin,gc.translate
local gc_draw,gc_rectangle,gc_circle=gc.draw,gc.rectangle,gc.circle
local int,rnd=math.floor,math.random
local char,byte=string.char,string.byte
local ins,rem=table.insert,table.remove
local gc_draw,gc_rectangle=gc.draw,gc.rectangle
@@ -21,6 +16,7 @@ end
--Royale mode
function randomTarget(P)--Return a random opponent for P
local rnd=math.random
if #PLY_ALIVE>1 then
local R
repeat
@@ -100,6 +96,7 @@ function royaleLevelup()
P.gameEnv.drop=spd
end
if GAME.curMode.name:find("_u")then
local int=math.floor
for i=1,#PLY_ALIVE do
local P=PLY_ALIVE[i]
P.gameEnv.drop=int(P.gameEnv.drop*.3)
@@ -113,108 +110,6 @@ end
--Virtualkey
local VK=virtualkey
function drawVirtualkeys()
if SETTING.VKSwitch then
local a=SETTING.VKAlpha
local _
if SETTING.VKIcon then
local icons=TEXTURE.VKIcon
for i=1,#VK do
if VK[i].ava then
local B=VK[i]
gc_setColor(1,1,1,a)
gc_setLineWidth(B.r*.07)
gc_circle("line",B.x,B.y,B.r,10)--Button outline
_=VK[i].pressTime
gc_setColor(B.color[1],B.color[2],B.color[3],a)
gc_draw(icons[i],B.x,B.y,nil,B.r*.026+_*.08,nil,18,18)--Icon
if _>0 then
gc_setColor(1,1,1,a*_*.08)
gc_circle("fill",B.x,B.y,B.r*.94,10)--Glow when press
gc_circle("line",B.x,B.y,B.r*(1.4-_*.04),10)--Ripple
end
end
end
else
for i=1,#VK do
if VK[i].ava then
local B=VK[i]
gc_setColor(1,1,1,a)
gc_setLineWidth(B.r*.07)
gc_circle("line",B.x,B.y,B.r,10)
_=VK[i].pressTime
if _>0 then
gc_setColor(1,1,1,a*_*.08)
gc_circle("fill",B.x,B.y,B.r*.94,10)
gc_circle("line",B.x,B.y,B.r*(1.4-_*.04),10)
end
end
end
end
end
end
function onVirtualkey(x,y)
local dist,nearest=1e10
for K=1,#VK do
local B=VK[K]
if B.ava then
local d1=(x-B.x)^2+(y-B.y)^2
if d1<B.r^2 then
if d1<dist then
nearest,dist=K,d1
end
end
end
end
return nearest
end
function pressVirtualkey(t,x,y)
local SETTING=SETTING
local B=VK[t]
B.isDown=true
B.pressTime=10
if x then
if SETTING.VKTrack then
--Auto follow
local O=VK_org[t]
local _FW,_CW=SETTING.VKTchW,1-SETTING.VKCurW
local _OW=1-_FW-_CW
--(finger+current+origin)
B.x=x*_FW+B.x*_CW+O.x*_OW
B.y=y*_FW+B.y*_CW+O.y*_OW
--Button collision (not accurate)
if SETTING.VKDodge then
for i=1,#VK do
local b=VK[i]
local d=B.r+b.r-((B.x-b.x)^2+(B.y-b.y)^2)^.5--Hit depth(Neg means distance)
if d>0 then
b.x=b.x+(b.x-B.x)*d*b.r*2.6e-5
b.y=b.y+(b.y-B.y)*d*b.r*2.6e-5
end
end
end
end
SFX.play("virtualKey",SETTING.VKSFX)
VIB(SETTING.VKVIB)
end
end
function updateVirtualkey()
if SETTING.VKSwitch then
for i=1,#VK do
local _=VK[i]
if _.pressTime>0 then
_.pressTime=_.pressTime-1
end
end
end
end
--Game
function generateLine(hole)
return 1023-2^(hole-1)
@@ -272,6 +167,7 @@ function scoreValid()--Check if any unranked mods are activated
return true
end
function destroyPlayers()--Destroy all player objects, restore freerows and free CCs
local rem=table.remove
for i=#PLAYERS,1,-1 do
local P=PLAYERS[i]
if P.canvas then P.canvas:release()end
@@ -290,23 +186,6 @@ function destroyPlayers()--Destroy all player objects, restore freerows and free
TABLE.clear(PLY_ALIVE)
collectgarbage()
end
function restoreVirtualkey()
for i=1,#VK_org do
local B,O=virtualkey[i],VK_org[i]
B.ava=O.ava
B.x=O.x
B.y=O.y
B.r=O.r
B.color=O.color
B.isDown=false
B.pressTime=0
end
for k,v in next,PLAYERS[1].keyAvailable do
if not v then
virtualkey[k].ava=false
end
end
end
function pauseGame()
if not SCN.swapping then
if not GAME.replaying then
@@ -485,7 +364,7 @@ do--function resetGameData(args)
GAME.replaying=1
else
GAME.frameStart=args:find("n")and 0 or 150-SETTING.reTime*15
GAME.seed=seed or rnd(1046101471,2662622626)
GAME.seed=seed or math.random(1046101471,2662622626)
GAME.pauseTime=0
GAME.pauseCount=0
GAME.saved=false
@@ -500,7 +379,7 @@ do--function resetGameData(args)
destroyPlayers()
GAME.curMode.load()
initPlayerPosition(args:find("q"))
restoreVirtualkey()
VK.restore()
if GAME.modeEnv.task then
for i=1,#PLAYERS do
PLAYERS[i]:newTask(GAME.modeEnv.task)
@@ -508,7 +387,7 @@ do--function resetGameData(args)
end
BG.set(GAME.modeEnv.bg)
local bgm=GAME.modeEnv.bgm
BGM.play(type(bgm)=="string"and bgm or type(bgm)=="table"and bgm[rnd(#bgm)])
BGM.play(type(bgm)=="string"and bgm or type(bgm)=="table"and bgm[math.random(#bgm)])
TEXT.clear()
if GAME.modeEnv.royaleMode then
@@ -566,146 +445,6 @@ do--function checkWarning()
end
end
--[[
Table data format:
{frame,event, frame,event, ...}
Byte data format: (1 byte each period)
dt, event, dt, event, ...
all data range from 0 to 127
large value will be encoded as 1xxxxxxx(high)-1xxxxxxx-...-0xxxxxxx(low)
Example (decoded):
6,1, 20,-1, 0,2, 26,-2, 872,4, ...
This means:
Press key1 at 6f
Release key1 at 26f (6+20)
Press key2 at the same time (26+0)
Release key 2 after 26 frame (26+26)
Press key 4 after 872 frame (52+872)
...
]]
function dumpRecording(list,ptr)
local out=""
local buffer,buffer2=""
if not ptr then ptr=1 end
local prevFrm=list[ptr-2]or 0
while list[ptr]do
--Flush buffer
if #buffer>10 then
out=out..buffer
buffer=""
end
--Encode time
local t=list[ptr]-prevFrm
prevFrm=list[ptr]
if t>=128 then
buffer2=char(t%128)
t=int(t/128)
while t>=128 do
buffer2=char(128+t%128)..buffer2
t=int(t/128)
end
buffer=buffer..char(128+t)..buffer2
else
buffer=buffer..char(t)
end
--Encode event
t=list[ptr+1]
if t>=128 then
buffer2=char(t%128)
t=int(t/128)
while t>=128 do
buffer2=char(128+t%128)..buffer2
t=int(t/128)
end
buffer=buffer..char(128+t)..buffer2
else
buffer=buffer..char(t)
end
--Step
ptr=ptr+2
end
return out..buffer,ptr
end
function pumpRecording(str,L)
local len=#str
local p=1
local curFrm=L[#L-1]or 0
local code
while p<=len do
--Read delta time
code=0
local b=byte(str,p)
while b>=128 do
code=code*128+b-128
p=p+1
b=byte(str,p)
end
curFrm=curFrm+code*128+b
L[#L+1]=curFrm
p=p+1
local event=0
b=byte(str,p)
while b>=128 do
event=event*128+b-128
p=p+1
b=byte(str,p)
end
L[#L+1]=event*128+b
p=p+1
end
end
do--function saveRecording()
local noRecList={"custom","solo","round","techmino"}
local function getModList()
local res={}
for _,v in next,GAME.mod do
if v.sel>0 then
ins(res,{v.no,v.sel})
end
end
return res
end
function saveRecording()
--Filtering modes that cannot be saved
for _,v in next,noRecList do
if GAME.curModeName:find(v)then
LOG.print("Cannot save recording of this mode now!",COLOR.N)
return
end
end
--File contents
local fileName="replay/"..os.date("%Y_%m_%d_%a_%H%M%S.rep")
local fileHead=
os.date("%Y/%m/%d %A %H:%M:%S\n")..
GAME.curModeName.."\n"..
VERSION.string.."\n"..
"Local Player"
local fileBody=
GAME.seed.."\n"..
JSON.encode(GAME.setting).."\n"..
JSON.encode(getModList()).."\n"..
dumpRecording(GAME.rep)
--Write file
if not love.filesystem.getInfo(fileName)then
love.filesystem.write(fileName,fileHead.."\n"..data.compress("string","zlib",fileBody))
ins(REPLAY,fileName)
FILE.save(REPLAY,"conf/replay")
return true
else
LOG.print("Save failed: File already exists")
end
end
end
--Game draw