@Creator27 It’s still really jerky even if I move my finger slow. Tha faster I move, the larger the jumps from position to position.
@dave1707, try changing the duration of the tween to see what works for you.
@dave1707, if that doesn’t work then try changing updatePositions() to this:
function updatePositions(state, pos)
local interpolation = tween(0.1, state, {playerX = pos.x, playerY = pos.y})
state["waypointId"] = interpolation
end
@Creator27 I replaced the whole function and it seems to be just as jerky.
Do you know anyone with an iPad. I would suggest you get them a copy of Codea so you can have access to 2 iPads to work on this. It’s been 4 months and things aren’t going like you want them. It’s would be a lot easier if you can see what’s happening as you make changes.
@dave1707, I (once again) have no hope that this is gonna work, but here it is:
function setup()
socket = require("socket")
parameter.action("Create Room", createRoom)
parameter.action("Join Room", function()
if other_ip then
joinRoom(other_ip, false)
else
parameter.text("IP", "", function(t)
other_ip = t
end)
end
end)
parameter.action("Find Room", function()
findRoom()
end)
client = socket.udp()
client:settimeout(0)
-- We need to create a table that can hold information about our server, if you end up making one
server_info = {players = 0, clients = {}, world_state = {}, puppet_states = {}, ids_taken = {}}
-- We also need to create a table that can hold info that the client has
client_info = {serverIp = "", world_state = {}}
other_ip = nil
current_time = nil
current_room_count = 1
tick = 0
finding_room = false
server = false
joinedRoom = false
myPlayerServer = nil
myPlayerClient = nil
sendNumber = 0
sendInterval = 0
playerTick = 0
end
function createRoom()
-- We need to find your address, so we create a new UDP socket and assign it a random IP
local ip, port = getLocalIP()
client:setsockname("*", "14285")
local ip2, port2 = client:getsockname()
client:setoption("broadcast", true)
client:setoption("dontroute", true)
your_ip = ip2
your_port = port2
print("Room created!")
print("Connect to "..ip)
server = true
end
function joinRoom(ip, finding_room)
if server == false then
if ip ~= "*" then
if finding_room == false then
print("Attempting to join the room...")
end
-- The port for all the servers is the same, so we only need the IP address of the server
client:setpeername(ip, "14285")
client:send("connection confirmation")
current_time = os.time()
else
print("Address not allowed!")
end
else
print("You are already hosting a server!")
end
end
function findRoom()
if server == false then
print("Attempting to find a room...")
finding_room = true
local ip, port = getLocalIP()
local ip1, ip2 = string.match(ip, "(%d+.%d+.%d+.)(%d+)")
local success, err = pcall(function()
for z = 1, 255 do
client:setpeername(ip1..z, "14285")
client:send("requesting server info")
end
client:setpeername("*")
client:setsockname("*", "14285")
end)
if success == false then
-- An error occured whether that be no internet connection or message wasn't received
print("An error occured! Please check your internet connection, and try again later.")
return
end
current_time = os.time()
else
print("You are already hosting a server!")
end
end
function sendMessage(msg)
if server == true then
for i,c in pairs(server_info["clients"]) do
client:sendto(tostring(msg), c.ip, c.port)
end
end
end
function leaveRoom()
-- We need to notify the server that we are leaving, so we send a packet to them
player:send("disconnection confirmation")
end
function resetParameters(params, args)
parameter.clear()
for i = 1, #params do
parameter.action(params[i], args[i])
end
end
function getLocalIP()
local udp = socket.udp()
udp:setpeername("192.167.188.122", "14285")
local ip, port = udp:getsockname()
udp:close()
return ip, port
end
function receiveData()
if server == true then
local msg, ip, port = client:receivefrom()
if msg ~= nil then
if msg == "connection confirmation" then
if server_info["players"] < 32 then
-- We can now add 1 more to our player count
server_info["players"] = server_info["players"] + 1
-- We now need to store the clients IP and port, so we can send them messages later
local uid = {ip = ip, port = port}
if not server_info["clients"][uid] then
table.insert(server_info["clients"], uid)
end
-- We now create a random ID for the connecting peer so we can differentiate between players on the server
local playerID = math.random(10000, 99999)
if not server_info["ids_taken"][playerID] then
server_info["ids_taken"][playerID] = playerID
else
playerID = math.random(10000, 99999)
end
client:sendto("valid confirmation"..playerID, ip, port)
client:sendto("peer address info"..json.encode(uid), ip, port)
-- We need to send the joining client our IP, so they can send messages to us later
local our_ip, our_port = getLocalIP()
client:sendto("server ip"..our_ip, ip, port)
-- We can now send everyone that has joined this room a packet telling them the amount of players in the room
for i,c in pairs(server_info["clients"]) do
client:sendto("player count"..tostring(server_info["players"]), c.ip, c.port)
end
else
-- We don't have enough room for another player, so we send the peer a message telling them to disconnect
local reason = "Max players inside the room!"
client:sendto("invalid confirmation"..reason, ip, port)
end
elseif msg == "requesting server info" then
-- We need to find your address, so we create a new UDP socket and assign it a random IP
local our_ip, our_port = getLocalIP()
-- We now know that somebody is trying to find a server, so we send a packet back to them with our server IP and port
local uid = {ip = our_ip}
client:sendto("server info"..json.encode(uid), ip, port)
elseif msg and string.find(msg, "disconnection confirmation") then
-- We know that one of the clients connected to this server wants to leave, so we send a packet back telling them that we have been notified
client:sendto("notified of disconnection", ip, port)
local uid = {ip = ip, port = port}
local clientInfo
local clientState
for i = 1, #server_info["clients"] do
if server_info["clients"][i] == uid then
clientInfo = i
end
end
for i = 1, #server_info["world_state"] do
local state = server_info["world_state"][i]
if state["addrInfo"].ip == uid.ip and state["addrInfo"].port == uid.port then
clientState = i
end
end
table.remove(server_info["clients"], clientInfo)
table.remove(server_info["world_state"], clientState)
print("server: "..json.encode(server_info["world_state"]))
-- We also need to deduct the player count
server_info["players"] = server_info["players"] - 1
elseif msg and string.find(msg, "client state") then
-- A connected peer has sent their client state to us, so we update our world state accordingly
local clientState = json.decode(string.sub(msg, 13, #msg))
local hasClientState = false
local existingState = nil
for i,s in pairs(server_info["world_state"]) do
if s.playerName == clientState.playerName then
hasClientState = true
existingState = s
break
end
end
if hasClientState == true then
local uid = {ip = ip, port = port}
if clientState.sendNumber > existingState.sendNumber then
existingState.sendNumber = clientState.sendNumber
-- We now also add a new waypoint for our puppet peer to follow
local waypoint = {x = clientState.playerX, y = clientState.playerY}
-- We now interpolate to the new state position
if existingState["waypointId"] == nil then
updatePositions(existingState, waypoint)
end
end
else
if not server_info["world_state"][clientState] then
table.insert(server_info["world_state"], clientState)
end
end
end
end
else
if finding_room == false then
local result = client:receive()
if result and string.find(result, "valid confirmation") then
-- We know that we successfully joined the room, and we can now receive messages from the server!
print("Successfully joined the room!")
joinedRoom = true
current_time = nil
parameter.clear()
-- We now create a button that allows the player to leave the room
local paramName = {"Leave Room"}
local paramArgs = {function() leaveRoom() end}
resetParameters(paramName, paramArgs)
-- We now set our player name to the ID that the server sent us
local playerID = string.sub(result, 19, #result)
local playerTab = {playerName = playerID, playerX = WIDTH/2, playerY = HEIGHT/2}
myPlayerClient = playerTab
if not client_info["world_state"][myPlayerClient] then
table.insert(client_info["world_state"], myPlayerClient)
end
client:setoption("dontroute", true)
elseif result and string.find(result, "peer address info") then
local addrInfo = json.decode(string.sub(result, 18, #result))
if myPlayerClient then
myPlayerClient["addrInfo"] = addrInfo
end
elseif result and string.find(result, "server ip") then
-- Now that we have the servers IP address, we can message them later if we need to
local serverIp = string.sub(result, 10, #result)
client_info["serverIp"] = serverIp
elseif result and string.find(result, "player count") then
-- We now know the current amount of players in our room, for now at least
local count = string.sub(result, 13, #result)
print("Player count: "..count)
elseif result and string.find(result, "invalid confirmation") then
-- We can now see the reason for our invalid confirmation and display it
local reason = string.sub(result, 21, #result)
print("Could not join the room: "..reason)
current_time = nil
-- We can now also remove the address and port set for our peer
client:setpeername("*")
elseif result == "notified of disconnection" then
-- We know that we can now safely leave the server
client:setpeername("*")
local removingState
for i,s in pairs(client_info["world_state"]) do
if s["addrInfo"].ip == myPlayerClient.addrInfo.ip and s["addrInfo"].port == myPlayerClient.addrInfo.port then
removingState = i
end
end
table.remove(client_info["world_state"], removingState)
print("client: "..json.encode(client_info["world_state"]))
joinedRoom = false
other_ip = nil
print("Successfully left the room!")
local paramNames = {"Create Room", "Join Room", "Find Room"}
local paramArgs = {createRoom, function()
if other_ip then
joinRoom(other_ip, false)
else
parameter.text("IP", "", function(t)
other_ip = t
end)
end
end, findRoom}
resetParameters(paramNames, paramArgs)
elseif result and string.find(result, "update client side") then
-- The server has sent us a update packet, so we fetch the state and update our world state
local state = json.decode(string.sub(result, 19, #result))
local oldState = nil
local foundState = false
for i,s in pairs(client_info["world_state"]) do
if s.playerName == state.playerName then
oldState = s
foundState = true
break
end
end
if foundState == true then
oldState.playerX = state.playerX
oldState.playerY = state.playerY
end
elseif result == nil then
if current_time then
if finding_room == false then
if os.time() > current_time + 5 then
-- If we get no response back for 5 seconds or more, we know it didn't work
print("Failed to connect, please try again later")
current_time = nil
end
end
end
end
else
local result, ip, port = client:receivefrom()
if result and string.find(result, "server info") then
-- Now we can attempt to join the room with the given IP address
local tab = json.decode(string.sub(result, 12, #result))
if finding_room == true then
joinRoom(tab.ip, true)
finding_room = false
end
else
if finding_room == true then
if current_time and os.time() > current_time + 15 then
-- If we get no response back for 15 seconds or more, we know we couldn't find a room
print("Failed to find a room!")
current_time = nil
end
end
end
end
end
end
function updatePositions(state, pos)
local interpolation
state["waypointId"] = interpolation
interpolation = tween(0.075, state, {playerX = pos.x, playerY = pos.y}, tween.easing.linear, function()
state["waypointId"] = nil
end)
end
function touched(touch)
if touch.state ~= ENDED and touch.state ~= CANCELLED then
if touch.state == BEGAN or touch.state == CHANGED then
if joinedRoom == true then
if myPlayerClient then
myPlayerClient.playerX = CurrentTouch.x
myPlayerClient.playerY = CurrentTouch.y
sendNumber = sendNumber + 1
end
end
end
end
end
function updatePlayers()
-- We now update the position of our player puppets, so it looks like the players are being updated in realtime
if server == false then
if joinedRoom == true then
for i,cp in pairs(client_info["world_state"]) do
fill(0, 255, 0)
text("client side", cp.playerX, cp.playerY + 30)
ellipse(cp.playerX, cp.playerY, 35)
end
end
else
for i,sp in pairs(server_info["world_state"]) do
fill(255, 13, 0)
text("server side", sp.playerX, sp.playerY + 30)
ellipse(sp.playerX, sp.playerY, 35)
end
end
end
-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)
-- This sets the line thickness
strokeWidth(5)
-- Do your drawing here
updatePlayers()
receiveData()
if myPlayerClient and joinedRoom == true and myPlayerClient.addrInfo ~= nil then
local playerTab = {playerName = myPlayerClient.playerName, playerX = myPlayerClient.playerX, playerY = myPlayerClient.playerY, sendNumber = sendNumber, addrInfo = myPlayerClient.addrInfo}
sendInterval = sendInterval + 1
if sendInterval >= 3 then
client:send("client state"..json.encode(playerTab))
sendInterval = 0
end
end
end
1 Like
An error occured! Please check your internet connection, and try again later.
@dave1707, try it now.
@Creator27 Still jerky.