新增virtualKey模块整理虚拟按键相关代码,整理代码
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user