340 lines
7.0 KiB
Lua
340 lines
7.0 KiB
Lua
local data=love.data
|
|
local gc=love.graphics
|
|
local tc=love.touch
|
|
|
|
local playerData
|
|
local ins,rem=table.insert,table.remove
|
|
local sin=math.sin
|
|
|
|
local SCR=SCR
|
|
local VK=virtualkey
|
|
local onVirtualkey=onVirtualkey
|
|
local pressVirtualkey=pressVirtualkey
|
|
local updateVirtualkey=updateVirtualkey
|
|
|
|
local hideChatBox
|
|
local textBox=WIDGET.newTextBox{name="texts",x=340,y=80,w=600,h=550,hide=function()return hideChatBox end}
|
|
local function switchChat()
|
|
hideChatBox=not hideChatBox
|
|
end
|
|
|
|
|
|
local playerInitialized
|
|
local playing
|
|
local heartBeatTimer
|
|
local lastUpstreamTime
|
|
local upstreamProgress
|
|
local lastBackTime=0
|
|
local noTouch,noKey=false,false
|
|
local touchMoveLastFrame=false
|
|
|
|
local scene={}
|
|
|
|
function scene.sceneBack()
|
|
wsWrite("Q")
|
|
WSCONN=false
|
|
LOG.print(text.wsDisconnected,"warn")
|
|
love.keyboard.setKeyRepeat(true)
|
|
end
|
|
function scene.sceneInit()
|
|
love.keyboard.setKeyRepeat(false)
|
|
TASK.new(TICK_wsRead)
|
|
hideChatBox=true
|
|
playerInitialized=false
|
|
textBox:clear()
|
|
|
|
playerData={}
|
|
resetGameData("n",playerData)
|
|
noTouch=not SETTING.VKSwitch
|
|
playing=false
|
|
lastUpstreamTime=0
|
|
upstreamProgress=1
|
|
heartBeatTimer=0
|
|
end
|
|
|
|
function scene.touchDown(x,y)
|
|
if noTouch then return end
|
|
|
|
local t=onVirtualkey(x,y)
|
|
if t then
|
|
PLAYERS[1]:pressKey(t)
|
|
pressVirtualkey(t,x,y)
|
|
end
|
|
end
|
|
function scene.touchUp(x,y)
|
|
if noTouch then return end
|
|
|
|
local t=onVirtualkey(x,y)
|
|
if t then
|
|
PLAYERS[1]:releaseKey(t)
|
|
end
|
|
end
|
|
function scene.touchMove()
|
|
if noTouch or touchMoveLastFrame then return end
|
|
touchMoveLastFrame=true
|
|
|
|
local L=tc.getTouches()
|
|
for i=#L,1,-1 do
|
|
L[2*i-1],L[2*i]=SCR.xOy:inverseTransformPoint(tc.getPosition(L[i]))
|
|
end
|
|
for n=1,#VK do
|
|
local B=VK[n]
|
|
if B.ava then
|
|
for i=1,#L,2 do
|
|
if(L[i]-B.x)^2+(L[i+1]-B.y)^2<=B.r^2 then
|
|
goto continue
|
|
end
|
|
end
|
|
PLAYERS[1]:releaseKey(n)
|
|
end
|
|
::continue::
|
|
end
|
|
end
|
|
function scene.keyDown(key)
|
|
if key=="escape"then
|
|
if TIME()-lastBackTime<1 then
|
|
SCN.back()
|
|
else
|
|
lastBackTime=TIME()
|
|
LOG.print(text.sureQuit,COLOR.orange)
|
|
end
|
|
elseif key=="\\"then
|
|
switchChat()
|
|
elseif playing then
|
|
if noKey then return end
|
|
local k=keyMap.keyboard[key]
|
|
if k and k>0 then
|
|
PLAYERS[1]:pressKey(k)
|
|
VK[k].isDown=true
|
|
VK[k].pressTime=10
|
|
end
|
|
elseif key=="space"then
|
|
if not PLAYERS[1].ready then
|
|
wsWrite("R")
|
|
end
|
|
end
|
|
end
|
|
function scene.keyUp(key)
|
|
if noKey then return end
|
|
local k=keyMap.keyboard[key]
|
|
if k and k>0 then
|
|
PLAYERS[1]:releaseKey(k)
|
|
VK[k].isDown=false
|
|
end
|
|
end
|
|
function scene.gamepadDown(key)
|
|
if key=="back"then
|
|
if TIME()-lastBackTime<1 then
|
|
WSCONN=false
|
|
SCN.back()
|
|
else
|
|
lastBackTime=TIME()
|
|
LOG.print(text.sureQuit,COLOR.orange)
|
|
end
|
|
else
|
|
if noKey then return end
|
|
local k=keyMap.joystick[key]
|
|
if k and k>0 then
|
|
PLAYERS[1]:pressKey(k)
|
|
VK[k].isDown=true
|
|
VK[k].pressTime=10
|
|
end
|
|
end
|
|
end
|
|
function scene.gamepadUp(key)
|
|
if noKey then return end
|
|
local k=keyMap.joystick[key]
|
|
if k and k>0 then
|
|
PLAYERS[1]:releaseKey(k)
|
|
VK[k].isDown=false
|
|
return
|
|
end
|
|
end
|
|
|
|
function scene.socketRead(mes)
|
|
local cmd=mes:sub(1,1)
|
|
local args=splitStr(mes:sub(2),";")
|
|
if cmd=="J"then
|
|
if playerInitialized then
|
|
local L=splitStr(args[1],",")
|
|
textBox:push{
|
|
COLOR.lR,L[1],
|
|
COLOR.dY,"#"..L[2].." ",
|
|
COLOR.Y,text.joinRoom,
|
|
}
|
|
end
|
|
for i=1,#args do
|
|
local L=splitStr(args[i],",")
|
|
ins(playerData,{name=L[1],id=L[2],sid=L[3],conf=L[4],ready=L[5]=="1"})
|
|
end
|
|
playerInitialized=true
|
|
SFX.play("click")
|
|
if not playing then
|
|
resetGameData("qn",playerData)
|
|
end
|
|
elseif cmd=="L"then
|
|
textBox:push{
|
|
COLOR.lR,args[1],
|
|
COLOR.dY,"#"..args[2].." ",
|
|
COLOR.Y,text.leaveRoom,
|
|
}
|
|
for i=1,#playerData do
|
|
if playerData[i].id==args[2]then
|
|
rem(playerData,i)
|
|
break
|
|
end
|
|
end
|
|
for i=1,#PLAYERS do
|
|
if PLAYERS[i].userID==args[2]then
|
|
rem(PLAYERS,i)
|
|
break
|
|
end
|
|
end
|
|
for i=1,#PLAYERS.alive do
|
|
if PLAYERS.alive[i].userID==args[2]then
|
|
rem(PLAYERS.alive,i)
|
|
break
|
|
end
|
|
end
|
|
initPlayerPosition(true)
|
|
elseif cmd=="T"then
|
|
textBox:push{
|
|
COLOR.W,args[1],
|
|
COLOR.dY,"#"..args[2].." ",
|
|
COLOR.sky,data.decode("string","base64",args[3])
|
|
}
|
|
elseif cmd=="C"then
|
|
if tostring(USER.id)~=args[2]then
|
|
for i=1,#playerData do
|
|
if playerData[i].id==args[2]then
|
|
playerData[i].conf=args[4]
|
|
playerData[i].p:setConf(args[4])
|
|
return
|
|
end
|
|
end
|
|
resetGameData("qn",playerData)
|
|
end
|
|
elseif cmd=="S"then
|
|
if playing and args[1]~=PLAYERS[1].subID then
|
|
for _,P in next,PLAYERS do
|
|
if P.subID==args[1]then
|
|
pumpRecording(data.decode("string","base64",args[2]),P.stream)
|
|
end
|
|
end
|
|
end
|
|
elseif cmd=="R"then
|
|
local L=PLAYERS.alive
|
|
for i=1,#L do
|
|
if L[i].subID==args[1]then
|
|
L[i].ready=true
|
|
SFX.play("reach",.6)
|
|
break
|
|
end
|
|
end
|
|
elseif cmd=="B"then
|
|
if not playing then
|
|
playing=true
|
|
lastUpstreamTime=0
|
|
upstreamProgress=1
|
|
resetGameData("n",playerData,tonumber(args[1]))
|
|
else
|
|
LOG.print("Redundant signal: B(begin)",30,COLOR.green)
|
|
end
|
|
elseif cmd=="F"then
|
|
playing=false
|
|
resetGameData("n",playerData)
|
|
for i=1,#playerData do
|
|
if playerData[i].sid==args[1]then
|
|
TEXT.show(text.champion:gsub("$1",playerData[i].name.."#"..playerData[i].id),640,260,80,"zoomout",.26)
|
|
break
|
|
end
|
|
end
|
|
else
|
|
LOG.print("Illegal message: ["..mes.."]",30,COLOR.green)
|
|
end
|
|
end
|
|
|
|
function scene.update(dt)
|
|
local _
|
|
local GAME=GAME
|
|
|
|
if not WSCONN and not SCN.swapping then SCN.back()end
|
|
if not playing then
|
|
heartBeatTimer=heartBeatTimer+dt
|
|
if heartBeatTimer>42 then
|
|
heartBeatTimer=0
|
|
wsWrite("P")
|
|
end
|
|
return
|
|
end
|
|
|
|
touchMoveLastFrame=false
|
|
updateVirtualkey()
|
|
|
|
GAME.frame=GAME.frame+1
|
|
if GAME.frame-lastUpstreamTime>8 then
|
|
local stream
|
|
stream,upstreamProgress=dumpRecording(GAME.rep,upstreamProgress)
|
|
if #stream>0 then
|
|
wsWrite("S"..data.encode("string","base64",stream))
|
|
else
|
|
ins(GAME.rep,GAME.frame+1)
|
|
ins(GAME.rep,0)
|
|
end
|
|
lastUpstreamTime=PLAYERS[1].alive and GAME.frame or 1e99
|
|
end
|
|
|
|
--Counting, include pre-das
|
|
if checkStart()then return end
|
|
|
|
--Update players
|
|
for p=1,#PLAYERS do
|
|
PLAYERS[p]:update(dt)
|
|
end
|
|
|
|
--Warning check
|
|
checkWarning()
|
|
end
|
|
|
|
function scene.draw()
|
|
local t=TIME()
|
|
if MARKING then
|
|
setFont(25)
|
|
gc.setColor(1,1,1,.2+.1*(sin(3*t)+sin(2.6*t)))
|
|
mStr(text.marking,190,60+26*sin(t))
|
|
end
|
|
|
|
--Players
|
|
for p=hideChatBox and 1 or 2,#PLAYERS do
|
|
PLAYERS[p]:draw()
|
|
end
|
|
|
|
--Virtual keys
|
|
drawVirtualkeys()
|
|
|
|
--Warning
|
|
gc.push("transform")
|
|
gc.origin()
|
|
if GAME.warnLVL>0 then
|
|
SHADER.warning:send("level",GAME.warnLVL)
|
|
gc.setShader(SHADER.warning)
|
|
gc.rectangle("fill",0,0,SCR.w,SCR.h)
|
|
gc.setShader()
|
|
end
|
|
gc.pop()
|
|
|
|
--New message
|
|
if textBox.new and hideChatBox then
|
|
setFont(30)
|
|
gc.setColor(1,TIME()%.4<.2 and 1 or 0,0)
|
|
gc.print("M",460,15)
|
|
end
|
|
end
|
|
scene.widgetList={
|
|
textBox,
|
|
WIDGET.newKey{name="ready",x=640,y=440,w=200,h=80,color="yellow",font=40,code=pressKey("space"),hide=function()return playing or not hideChatBox or PLAYERS[1].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=pressKey"escape"},
|
|
}
|
|
|
|
return scene |