浏览代码

Lag & desync compensation

tags/crossplatform
madiwka3 4 年前
父节点
当前提交
5d42a7c855
共有 4 个文件被更改,包括 172 次插入63 次删除
  1. +61
    -18
      main.lua
  2. +1
    -1
      readme.md
  3. +47
    -32
      server/server.lua
  4. +63
    -12
      src/baseGame.lua

+ 61
- 18
main.lua 查看文件

@@ -24,7 +24,7 @@ wall1width = 30
nuclearanimation = 3 nuclearanimation = 3
easternum = 0 easternum = 0
ball_DIR = 0 ball_DIR = 0
updaterate = 0.03 updaterate = 0.015
RED = 255 RED = 255
hitNum = {} hitNum = {}
hitNum[1] = 0 hitNum[1] = 0
@@ -201,6 +201,7 @@ function love.load()
newButton( newButton(
"Online", "Online",
function() function()
MAP_TYPE = 0
gameState = "chooseIP" gameState = "chooseIP"
end end
) )
@@ -291,15 +292,15 @@ function love.load()
end end
) )
) )
table.insert( --table.insert(
settings, -- settings,
newButton( -- newButton(
"Change Map", -- "Change Map",
function() -- function()
MAP_TYPE = MAP_TYPE + 1 -- MAP_TYPE = MAP_TYPE + 1
end -- end
) -- )
) --)
table.insert( table.insert(
settings, settings,
newButton( newButton(
@@ -588,6 +589,7 @@ function love.load()
function() function()
gameState = "1serve" gameState = "1serve"
gameMode = "reversegame" gameMode = "reversegame"
globalState = "base"
end end
) )
) )
@@ -763,6 +765,7 @@ function nettest(dt)
for i = 1, maxBalls do for i = 1, maxBalls do
ts = ts + dt ts = ts + dt
if ts > updaterate then if ts > updaterate then
if ball[1].dx <= 0 then
--print (tostring(ball[i].dy)) --print (tostring(ball[i].dy))
udp:send(tostring(lastSentKey) .. udp:send(tostring(lastSentKey) ..
'|' .. tostring(ball[i].dy) .. '|' .. tostring(ball[i].dy) ..
@@ -777,8 +780,12 @@ function nettest(dt)
'|' .. gameState .. '|' .. gameState ..
'|' .. tostring(ball[i].dx) .. '|' .. tostring(ball[i].dx) ..
'|' .. tostring(ballSpeed) .. '|' .. tostring(ballSpeed) ..
'|' .. tostring(paddle_SPEED) ..
"|HOST") "|HOST")
print("SENT: " .. lastSentKey) print("PRIVILEGE SENT: " .. lastSentKey)
else
udp:send(tostring(lastSentKey) ..'|' .. player1.y .. "|HOST")
end
ts = 0 ts = 0
end end
end end
@@ -795,14 +802,23 @@ function nettest(dt)
print("ReceivedINFO: " .. data) print("ReceivedINFO: " .. data)
confirmation = "N" confirmation = "N"
local p = split(data, '|') local p = split(data, '|')
if p[3] ~= "CLIENT" then if p[3] ~= "CLIENT" and not p[15] then
confirmation = "U" confirmation = "U"
end end
if p[15] then
if p[15] ~= "CLIENT" then
confirmation = "U"
end
end
if tonumber(p[4]) > 90 then if tonumber(p[4]) > 90 then
confirmation = "L" confirmation = "L"
end end
if ball[1].dx <= 0 then
lastSentKeyClient = p[1] lastSentKeyClient = p[1]
player2.y = tonumber(p[2]) player2.y = tonumber(p[2])
elseif ball[1].dx > 0 then
lastSentKeyClient, ball[i].dy, player2.y, player1score, player2score, player1nukescore, player2nukescore, ball[i].x, ball[i].y, gameState, ball[i].dx, ballSpeed, paddle_SPEED = p[1], die, tonumber(p[4]), tonumber(p[5]), tonumber(p[6]), tonumber(p[7]), tonumber(p[8]), tonumber(p[9]), tonumber(p[10]), p[11], tonumber(p[12]), tonumber(p[13]), tonumber(p[14])
end
end end
until not data until not data
@@ -829,7 +845,27 @@ function clienttest(dt)
end end
ts = ts + dt ts = ts + dt
if ts > updaterate then if ts > updaterate then
if ball[1].dx <= 0 then
print("MINOR SENDING")
udp:send(tostring(lastSentKey) ..'|' .. player2.y .. "|CLIENT") udp:send(tostring(lastSentKey) ..'|' .. player2.y .. "|CLIENT")
elseif ball[1].dx > 0 then
print("PRIVILEGED SENDING")
udp:send(tostring(lastSentKey) ..
'|' .. tostring(ball[1].dy) ..
'|' .. tostring(player1.y) ..
'|' .. tostring(player2.y) ..
'|' .. tostring(player1score) ..
'|' .. tostring(player2score) ..
'|' .. tostring(player1nukescore) ..
'|' .. tostring(player2nukescore) ..
'|' .. tostring(ball[1].x) ..
'|' .. tostring(ball[1].y) ..
'|' .. gameState ..
'|' .. tostring(ball[1].dx) ..
'|' .. tostring(ballSpeed) ..
'|' .. tostring(paddle_SPEED) ..
"|CLIENT")
end
ts = 0 ts = 0
end end
local data local data
@@ -846,18 +882,25 @@ function clienttest(dt)
print("SENT TO SERVER:" .. lastSentKey) print("SENT TO SERVER:" .. lastSentKey)
confirmation = "N" confirmation = "N"
local p = split(data, '|') local p = split(data, '|')
if p[14] then if p[15] then
if p[14] ~= "HOST" then if p[15] ~= "HOST" then
confirmation = "U" confirmation = "U"
end end
if tonumber(p[15]) > 90 then if tonumber(p[16]) > 90 then
confirmation = "L" confirmation = "L"
end end
for i = 1, maxBalls do for i = 1, maxBalls do
local die = tonumber(p[2]) local die = tonumber(p[2])
lastSentKeyClient, ball[i].dy, player1.y, player1score, player2score, player1nukescore, player2nukescore, ball[i].x, ball[i].y, gameState, ball[i].dx, ballSpeed = p[1], die, tonumber(p[4]), tonumber(p[5]), tonumber(p[6]), tonumber(p[7]), tonumber(p[8]), tonumber(p[9]), tonumber(p[10]), p[11], tonumber(p[12]), tonumber(p[13]) if ball[i].dx <= 0 then
lastSentKeyClient, ball[i].dy, player1.y, player1score, player2score, player1nukescore, player2nukescore, ball[i].x, ball[i].y, gameState, ball[i].dx, ballSpeed, paddle_SPEED = p[1], die, tonumber(p[4]), tonumber(p[5]), tonumber(p[6]), tonumber(p[7]), tonumber(p[8]), tonumber(p[9]), tonumber(p[10]), p[11], tonumber(p[12]), tonumber(p[13]), tonumber(p[14])
elseif ball[i].dx > 0 then
lastSentKeyClient = p[1]
player1.y = tonumber(p[4])
end end
end end
elseif p[3] ~= "HOST" then
confirmation = "U"
end
end end
print("GOT: " .. lastSentKeyClient) print("GOT: " .. lastSentKeyClient)
until not data until not data
@@ -1360,7 +1403,7 @@ function love.draw()
baseDraw() baseDraw()
if (globalState == "nettest" or globalState == "clienttest") and confirmation == "D" then if (globalState == "nettest" or globalState == "clienttest") and confirmation == "D" then
love.graphics.clear(50 / 255, 50 / 255, 50 / 255, 255) love.graphics.clear(50 / 255, 50 / 255, 50 / 255, 255)
love.graphics.printf("WAIT FOR PLAYER 2", 0, VIRTUAL_HEIGHT / 2, VIRTUAL_WIDTH, "center") love.graphics.printf("WAIT FOR OPPONENT", 0, VIRTUAL_HEIGHT / 2, VIRTUAL_WIDTH, "center")
end end
if (globalState == "nettest" or globalState == "clienttest") and confirmation == "U" then if (globalState == "nettest" or globalState == "clienttest") and confirmation == "U" then
love.graphics.clear(50 / 255, 50 / 255, 50 / 255, 255) love.graphics.clear(50 / 255, 50 / 255, 50 / 255, 255)


+ 1
- 1
readme.md 查看文件

@@ -32,4 +32,4 @@ To play on Windows, download and install <a href = "https://love2d.org">Love</a>
To play an old, outdated EXE version on Windows, head to <a href = "https://madi-wka.club/Downloads.php">my website</a>, and download the old, outdated game. To play an old, outdated EXE version on Windows, head to <a href = "https://madi-wka.club/Downloads.php">my website</a>, and download the old, outdated game.


# Changes # Changes
<p>0.7.6 is here! With this update, I improved the AI, allowing it to follow 2 balls at the same time! I also added "Smart" difficulty, where the AI uses physics and math to pre-calculate where the ball is going to land. Alpha-testing of the Online gameplay is now here, although its stupid and doesnt work. </p> <p>0.7.7 is here! Wiht this uodate, Online mode FINALLY, FINALLY WORKS! The default IP is my server, but you can launch the server from anywhere! The code for the server is under the server/ directory. The client is kind of laggy, though. I am trying my best to fix the issue. </p>

+ 47
- 32
server/server.lua 查看文件

@@ -1,15 +1,20 @@
local running = true local running = true
local socket = require 'socket' local socket = require 'socket'
local udp = socket.udp() local udp = socket.udp()
local player1ip, player2ip, p1data, p2data, player1port, player2port = "none", "none", nil, nil, nil, nil local player1ip, player2ip, player1port, player2port = "none", "none", nil, nil
udp:settimeout(0) udp:settimeout(0)
udp:setsockname('*', 12345) udp:setsockname('*', 12345)
local p1ping = 0 local p1ping = 0
local p2ping = 0 local p2ping = 0
local data, msg_or_ip, port_or_nil
while running do while running do
local data, msg_or_ip, port_or_nil
local p1data, p2data
repeat
data, msg_or_ip, port_or_nil = udp:receivefrom() data, msg_or_ip, port_or_nil = udp:receivefrom()
if data then if data then
print(string.sub(data,1,1) .. "Playerlist: " .. player1ip .. " " .. player2ip)
if (player1ip == msg_or_ip) then if (player1ip == msg_or_ip) then
p1ping = 0 p1ping = 0
p1data = data p1data = data
@@ -20,11 +25,13 @@ while running do
if (player1ip == "none") then if (player1ip == "none") then
player1ip = msg_or_ip player1ip = msg_or_ip
p1data = data p1data = data
p1ping = 0
player1port = port_or_nil player1port = port_or_nil
print("CONNECTED: PLAYER 1 FROM: " .. player1ip) print("CONNECTED: PLAYER 1 FROM: " .. player1ip)
elseif player2ip == "none" and msg_or_ip ~= player1ip then elseif player2ip == "none" and msg_or_ip ~= player1ip then
player2ip = msg_or_ip player2ip = msg_or_ip
p2data = data p2data = data
p2ping = 0
player2port = port_or_nil player2port = port_or_nil
print("CONNECTED: PLAYER 2 FROM: " .. player2ip) print("CONNECTED: PLAYER 2 FROM: " .. player2ip)
elseif (player1ip ~= msg_or_ip and player2ip ~= msg_or_ip) then elseif (player1ip ~= msg_or_ip and player2ip ~= msg_or_ip) then
@@ -32,38 +39,46 @@ while running do
end end
end end



else
elseif player1ip ~= "none" then end
p1ping = p1ping + 1 until not data
if p1ping > 5 then if player1ip ~= "none" then
if p2data then p1ping = p1ping + 1
udp:sendto(p2data .. '|' .. p1ping, player1ip, player1port) if p1ping > 100 then
end if p2data then
print("PLAYER 1 DISCONNECTED") udp:sendto(p2data .. '|' .. p1ping, player1ip, player1port)
p1data = nil
player1ip = "none"
player1port = nil
end
elseif player2ip ~= "none" then
p2ping = p2ping + 1
if p2ping > 5 then
if p1data then
udp:sendto(p1data .. '|' .. p2ping, player2ip, player2port)
end
print("PLAYER 2 DISCONNECTED")
p2data = nil
player2ip = "none"
player2port = nil
end end
print("PLAYER 1 DISCONNECTED")
p1data = nil
player1ip = "none"
player1port = nil
end end
if data then end
print(data .. "FROM " .. msg_or_ip .. "Playerlist: " .. player1ip .. " " .. player2ip) if player2ip ~= "none" then
end p2ping = p2ping + 1
if p1data and p2data then if p2ping > 100 then
if p1data then
udp:sendto(p1data .. '|' .. p2ping, player2ip, player2port) udp:sendto(p1data .. '|' .. p2ping, player2ip, player2port)
udp:sendto(p2data .. '|' .. p1ping, player1ip, player1port) end
print("SENT1: " .. player2ip .. " " .. player2port .. " " .. p1data) print("PLAYER 2 DISCONNECTED")
print("SENT2: " .. player1ip .. " " .. player1port .. " " .. p2data) p2data = nil
player2ip = "none"
player2port = nil
end end
socket.sleep(0.01) end
if p1data and player2port then
udp:sendto(p1data .. '|' .. p2ping, player2ip, player2port)
print("SENT TO " .. player2ip .. ":" .. player2port .. " : " .. string.sub(p1data,1,1))
end
if p2data and player1port then
udp:sendto(p2data .. '|' .. p1ping, player1ip, player1port)
print("SENT TO " .. player1ip .. ":" .. player1port .. " : " .. string.sub(p2data,1,1))
--print("1::" .. p1data)
--print("2::" .. p2data)
--print("SENT1: " .. player2ip .. " " .. player2port .. " " .. p1data)
--print("SENT2: " .. player1ip .. " " .. player1port .. " " .. p2data)
end
socket.sleep(0.015)

end end

+ 63
- 12
src/baseGame.lua 查看文件

@@ -1,5 +1,5 @@
function basegame(dt) function basegame(dt)
if gameMode == "reverse" then if gameMode == "reversegame" then
reversegame(dt) reversegame(dt)
end end
if player1nukescore > 300 then if player1nukescore > 300 then
@@ -89,7 +89,7 @@ function basegame(dt)
end end
if (striken == 1) then if (striken == 1) then
player1nukescore = player1nukescore * 1.2 player1nukescore = player1nukescore * 1.5
if (synctype == 0) then if (synctype == 0) then
paddle_SPEED = paddle_SPEED * 1.10 paddle_SPEED = paddle_SPEED * 1.10
elseif (synctype == 1) then elseif (synctype == 1) then
@@ -355,7 +355,7 @@ end
function debugCheck(dt) function debugCheck(dt)
if (gameState == "menu") then if (gameState == "menu") then
updateTEXT = "0.7.6 Chalkboard Update" updateTEXT = "0.7.7 Chalkboard Update"
end end
dangerChecker() dangerChecker()
elapsed = elapsed + dt elapsed = elapsed + dt
@@ -604,12 +604,7 @@ function normalDraw()
end end
end end


if gameMode == 'practice' then pongDraw()
practiceDraw()
end
if gameMode == 'normal' then
pongDraw()
end
love.graphics.setFont(smallfont) love.graphics.setFont(smallfont)
for i = 1, maxBalls do for i = 1, maxBalls do
if areanuclear == 1 then if areanuclear == 1 then
@@ -743,7 +738,7 @@ function baseDraw()
nuclearDraw() nuclearDraw()
end end
if gameState == 'play' or gameState == '1serve' or gameState == '2serve' or gameState == 'done' then if gameState == 'play' or gameState == '1serve' or gameState == '2serve' or gameState == 'done' then
--print("Drawing normally") print("Drawing normally")
normalDraw() normalDraw()
end end


@@ -1056,7 +1051,7 @@ function clientsBaseGame(dt)
end end
if (striken == 1) then if (striken == 1) then
player1nukescore = player1nukescore * 1.2 player1nukescore = player1nukescore * 1.5
if (synctype == 0) then if (synctype == 0) then
paddle_SPEED = paddle_SPEED * 1.10 paddle_SPEED = paddle_SPEED * 1.10
elseif (synctype == 1) then elseif (synctype == 1) then
@@ -1148,6 +1143,61 @@ function clientsBaseGame(dt)
player2nukescore = player2nukescore + 10 player2nukescore = player2nukescore + 10
ball[i].dx = -ball[i].dx ball[i].dx = -ball[i].dx
ball[i].x = player2.x - 30 ball[i].x = player2.x - 30
if ((love.keyboard.isDown(p2control.up))) then
select = math.random(1, 5)
if select == 1 then
ball[i].dy = -1
elseif select == 2 then
ball[i].dy = -1.2
elseif select == 3 then
ball[i].dy = -1.5
elseif select == 4 then
ball[i].dy = -1.8
elseif select == 5 then
ball[i].dy = -2
end
elseif (love.keyboard.isDown(p2control.down))then
select = math.random(1, 5)
if select == 1 then
ball[i].dy = 1
elseif select == 2 then
ball[i].dy = 1.2
elseif select == 3 then
ball[i].dy = 1.5
elseif select == 4 then
ball[i].dy = 1.8
elseif select == 5 then
ball[i].dy = 2
end
else
if ball[i].dy < 0 then
select = math.random(1, 5)
if select == 1 then
ball[i].dy = -1
elseif select == 2 then
ball[i].dy = -1.2
elseif select == 3 then
ball[i].dy = -1.5
elseif select == 4 then
ball[i].dy = -1.8
elseif select == 5 then
ball[i].dy = -2
end
else
select = math.random(1, 5)
if select == 1 then
ball[i].dy = 1
elseif select == 2 then
ball[i].dy = 1.2
elseif select == 3 then
ball[i].dy = 1.5
elseif select == 4 then
ball[i].dy = 1.8
elseif select == 5 then
ball[i].dy = 2
end
end
end
end end
hitIdentifier() hitIdentifier()
if ball[i].y <= 0 then if ball[i].y <= 0 then
@@ -1155,7 +1205,7 @@ function clientsBaseGame(dt)
sounds["wallhit"]:setPitch(ballSpeed / 250) sounds["wallhit"]:setPitch(ballSpeed / 250)
sounds["wallhit"]:play() sounds["wallhit"]:play()
ball[i].y = 0 ball[i].y = 0
ball[i].dy = -ball[i].dy
end end


-- -4 to account for the ball's size -- -4 to account for the ball's size
@@ -1164,6 +1214,7 @@ function clientsBaseGame(dt)
sounds["wallhit"]:setPitch(ballSpeed / 250) sounds["wallhit"]:setPitch(ballSpeed / 250)
sounds["wallhit"]:play() sounds["wallhit"]:play()
ball[i].y = VIRTUAL_HEIGHT - 40 ball[i].y = VIRTUAL_HEIGHT - 40
ball[i].dy = -ball[i].dy
end end
--love.window.setTitle('Trying to update the ball') --love.window.setTitle('Trying to update the ball')


||||||
x
 
000:0
正在加载...
取消
保存