Page 1 of 1

Weird stuff with udp socket and keyboard

Posted: Wed Jan 20, 2021 11:40 pm
by ditas
Hello there,
I'm working on online game and using love2d 11.3 (on Mac OS Catalina and Ubuntu 20.04). So I'm facing really strange issue:
on update, when I'm using udp:receivefrom() I got my love.keypressed(key) function messed up. So, I'm pressing UP and my object is going down etc.
Here's the code:

Code: Select all

 -- network test
local socket = require("socket")
local address, port = "127.0.0.1", 5555
local timeStamp
local updateRate = 0.1 -- 1/10 of sec
local client
local t
---------------

function love.load()
    require("staticClass")
    obstacles = {}

    require("dynamicClass")
    dynamic = Dynamic.new(500, 0, nil, nil, nil, nil, 10)
    dynamic2 = Dynamic.new(400, 0, nil, nil, nil, nil, 10)
    dynamic3 = Dynamic.new(300, 0, nil, nil, nil, nil, 10)
    dynamic4 = Dynamic.new(600, 0, nil, nil, nil, nil, 10)
    dynamic5 = Dynamic.new(700, 0, nil, nil, nil, nil, 10)

    obstacles = {dynamic, dynamic2, dynamic3, dynamic4, dynamic5}

    spawnObstacle(300, 300, 600, 50) -- create platform

    -- network test
    timeStamp = tostring(os.time())
    local dg = string.format("%s %d %s %s", 'init', timeStamp, 'test_match', 'test_player2')

    t = 0

    local ip = assert(socket.dns.toip(address))

    udp = socket.udp()
    udp:settimeout(5)
    udp:setpeername(address, port)
    udp:send(dg)
    udp:setpeername("*")
    ---------------

    gameState = 1
end

function love.update(dt)

    if gameState == 2 then
        if love.keyboard.isDown("q") then
            player = dynamic:update(dt, obstacles, "left")
        elseif love.keyboard.isDown("e") then
            player = dynamic:update(dt, obstacles, "right")
        else
            player = dynamic:update(dt, obstacles, "none")
        end    

        -- dynamic2:update(dt, obstacles, "none")
        dynamic3:update(dt, obstacles, "none")
        dynamic4:update(dt, obstacles, "none")
        dynamic5:update(dt, obstacles, "none")

        for i,o in ipairs(obstacles) do
            if o.type == "static" then
                o:update(dt)
            end
        end
    end

    -- network test
    t = t + dt

    if not client then
        data, from_ip, from_port = udp:receivefrom()
        -- print(data)
        -- print(from_ip)
        -- print(from_port)

        udp:setpeername(from_ip, from_port)
        client = udp
        client:settimeout(0)

        gameState = 2
    elseif t > updateRate then
        timeStamp = tostring(os.time())
        local dg = string.format("%s %d %f %f", 'move', timeStamp, player.x, player.y)
        client:send(dg)
        t = t - updateRate
    else
        update = client:receive()
        -- print(update)
        player_update = {}
        if update then
            for w in update:gmatch("%S+") do 
                -- print(w)
                table.insert(player_update, w)
            end

            dynamic2.x = tonumber(player_update[3])
            dynamic2.y = tonumber(player_update[4])
        end
    end
    ---------------
end
So, if I comment this line

Code: Select all

data, from_ip, from_port = udp:receivefrom()
as well as this one

Code: Select all

udp:setpeername(from_ip, from_port)
(to prevent error) I got my

Code: Select all

function love.keypressed(key)
    if key == "up" then
        dynamic:throwUp(5)
        -- dynamic2:throwUp(5)
    end
...
worked correctly, otherwise my object is going down instead of going up.
I totally ran out of ideas what is going on. Pls help

Re: Weird stuff with udp socket and keyboard

Posted: Thu Jan 21, 2021 12:33 am
by grump
Post the actual code. There is not love.keypressed in this code.

A runnable .love file would be helpful too.

Re: Weird stuff with udp socket and keyboard

Posted: Thu Jan 21, 2021 12:46 am
by ditas
here's the full main.lua code:

Code: Select all

-- network test
local socket = require("socket")
local address, port = "127.0.0.1", 5555
local timeStamp
local updateRate = 0.1 -- 1/10 of sec
local client
local t
---------------

function love.load()
    require("staticClass")
    obstacles = {}

    require("dynamicClass")
    dynamic = Dynamic.new(500, 0, nil, nil, nil, nil, 10)
    dynamic2 = Dynamic.new(400, 0, nil, nil, nil, nil, 10)
    dynamic3 = Dynamic.new(300, 0, nil, nil, nil, nil, 10)
    dynamic4 = Dynamic.new(600, 0, nil, nil, nil, nil, 10)
    dynamic5 = Dynamic.new(700, 0, nil, nil, nil, nil, 10)

    obstacles = {dynamic, dynamic2, dynamic3, dynamic4, dynamic5}

    spawnObstacle(300, 300, 600, 50) -- create platform

    -- network test
    timeStamp = tostring(os.time())
    local dg = string.format("%s %d %s %s", 'init', timeStamp, 'test_match', 'test_player2')

    t = 0

    local ip = assert(socket.dns.toip(address))

    udp = socket.udp()
    udp:settimeout(5)
    udp:setpeername(address, port)
    udp:send(dg)
    udp:setpeername("*")
    ---------------

    gameState = 1
end

function love.update(dt)

    if gameState == 2 then
        if love.keyboard.isDown("q") then
            player = dynamic:update(dt, obstacles, "left")
        elseif love.keyboard.isDown("e") then
            player = dynamic:update(dt, obstacles, "right")
        else
            player = dynamic:update(dt, obstacles, "none")
        end    

        -- dynamic2:update(dt, obstacles, "none")
        dynamic3:update(dt, obstacles, "none")
        dynamic4:update(dt, obstacles, "none")
        dynamic5:update(dt, obstacles, "none")

        for i,o in ipairs(obstacles) do
            if o.type == "static" then
                o:update(dt)
            end
        end
    end

    -- network test
    t = t + dt

    if not client then
        data, from_ip, from_port = udp:receivefrom()

        udp:setpeername(from_ip, from_port)
        client = udp
        client:settimeout(0)

        gameState = 2
    elseif t > updateRate then
        timeStamp = tostring(os.time())
        local dg = string.format("%s %d %f %f", 'move', timeStamp, player.x, player.y)
        client:send(dg)
        t = t - updateRate
    else
        update = client:receive()
        player_update = {}
        if update then
            for w in update:gmatch("%S+") do 
                -- print(w)
                table.insert(player_update, w)
            end

            dynamic2.x = tonumber(player_update[3])
            dynamic2.y = tonumber(player_update[4])
        end
    end
    ---------------
end

function love.draw()
    dynamic:draw()
    dynamic2:draw()
    dynamic3:draw()
    dynamic4:draw()
    dynamic5:draw()

    for i,o in ipairs(obstacles) do
        o:draw()
    end
    
    love.graphics.print("Current FPS: "..tostring(love.timer.getFPS( )), 10, 10)
end

function love.keypressed(key)
    if key == "up" then
        dynamic:throwUp(5)
    end
    if key == "left" then
        dynamic:throwAngle(50, 135)
    end
    if key == "right" then
        dynamic:throwAngle(50, 45)
    end
end

function spawnObstacle(x, y, width, height)
    obstacle = Static.new(x, y, nil, width, height)
    table.insert(obstacles, obstacle)
end

Re: Weird stuff with udp socket and keyboard

Posted: Sun Jan 24, 2021 8:25 pm
by gcmartijn
I din't read the code, but in the first days when I was working with testing, this information is important.
If you use UDP you don't have any guarantee that your message is send/received. I guess that this is not the issue here but its good to know.
For some things you want to use TCP because that will give you the guarantee the message is send/received , but its much slower.

Maybe you already know this, just want to share the info ;)