Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - io

Pages: [1]
1
Network / [Solved-ish] Movement Lag on Client
« on: March 04, 2013, 08:29:31 pm »
====
Update
====

Last update 6.21AM 10Mar2013 -8 GMT

Click:  http://en.sfml-dev.org/forums/index.php?topic=10803.msg74965#msg74965
to jump to latest update.

~~~~~~~~~~~~

I'm giving a dabble at SFML networking and I have what I think is probably a very basic issue/fundamental misunderstanding on my part.

I have created a server that sends out commands to a client in order to move a rectangle, however the client end is always lagged compared to the server as can be seen here:

http://www.youtube.com/watch?v=7LNnuwdrHUw

I haven't tried implementing UDP yet, and from what I've been reading real time movement should be implemented with UDP (I think most games are using UDP for this type of stuff/TCP for the chat). 

Is my understanding correct and I should move to UDP, or should TCP be able to handle something like this?

I can think of one possible way to eliminate this lag.  When the key is pressed on the server end have a move left sent and the client will continuously move until a move left end is received.. and this should synch it up better, but I'm wondering if there is a better approach.  Another possibility I thought of is just send the exact coords of where the client rectangle should be.

Thanks!  Any input/advice is greatly appreciated as always.


main.cpp
//#include "VoIP.hpp"
#include "tcp_issue.hpp"


int main( int argc, char* argv[])
{
    //voip example
    //voipExample();

    if( argc > 2 )
    {

        //tcp/udp issue
        issueServer( argv[1], argv[2] ); //[server,client] [tcp,udp]
    }

    return EXIT_SUCCESS;
}
 


tcp_issue.hpp
#include <SFML/Graphics.hpp>
#include <string>

const float MOVE_SPEED = 70;
const int PORT = 7777;

sf::TcpSocket socket;
sf::UdpSocket usocket;
sf::Mutex globalMutex;

std::string command = "";

bool quit = false;

void tcpServerListen();
void tcpClient();
void tcpSend();

void udpServer();
void udpClient();
void udpSend();

void issueServer( std::string mode, std::string method )
{
    std::cout << "Incoming mode: " << mode << std::endl;
    std::cout << "Incoming method: " << method << std::endl;

    sf::Thread threadServerTCP(&tcpServerListen);
    sf::Thread threadClientTCP(&tcpClient);
    sf::Thread threadServerUDP(&udpServer);
    sf::Thread threadClientUDP(&udpClient);

    if( mode.compare("server") == 0 )
    {
        std::cout << "Starting in server mode.\n";
        if( method.compare("tcp") == 0 )
        {
            std::cout << "Launching server tcp thread\n";
            threadServerTCP.launch();
        }
        else
        {
            std::cout << "Launching server udp thread\n";
            threadServerUDP.launch();
        }
    }
    else
    {
        std::cout << "Starting in client mode.\n";
        if( method.compare("tcp") == 0 )
        {
            std::cout << "Starting tcp client thread.\n";
            threadClientTCP.launch();
        }
        else
        {
            std::cout << "Starting udp client thread.\n";
            threadClientTCP.launch();
        }
    }


    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Playground");

    sf::Clock Clock;
    sf::Time time;

    sf::RectangleShape rectangle;
    rectangle.setSize(sf::Vector2f(100, 50));
    rectangle.setOutlineColor(sf::Color::Red);
    rectangle.setOutlineThickness(5);
    rectangle.setPosition(10, 20);

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                quit = true;

                if( method.compare("tcp") == 0 )
                    threadClientTCP.wait();
                else
                    threadClientUDP.wait();

                window.close();
            }
            if (event.type == sf::Event::KeyPressed)
            {
            }
        }
        if( mode.compare("server") == 0 )
        {
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
            {
                globalMutex.lock();
                command = "left";
                globalMutex.unlock();

                if( method.compare("tcp") == 0 )
                    tcpSend();
                else
                    udpSend();

                rectangle.move(-1*MOVE_SPEED*time.asSeconds(),0);
            }

            if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
            {
                globalMutex.lock();
                command = "down";
                globalMutex.unlock();

                if( method.compare("tcp") == 0 )
                    tcpSend();
                else
                    udpSend();

                rectangle.move(0,1*MOVE_SPEED*time.asSeconds());
            }

            if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
            {
                globalMutex.lock();
                command = "right";
                globalMutex.unlock();

                if( method.compare("tcp") == 0 )
                    tcpSend();
                else
                    udpSend();

                rectangle.move(1*MOVE_SPEED*time.asSeconds(),0);
            }

            if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
            {
                globalMutex.lock();
                command = "up";
                globalMutex.unlock();

                if( method.compare("tcp") == 0 )
                    tcpSend();
                else
                    udpSend();

                rectangle.move(0,-1*MOVE_SPEED*time.asSeconds());
            }
        }
        else
        {
            if (command.compare("left") == 0)
            {
                rectangle.move(-1*MOVE_SPEED*time.asSeconds(),0);

                globalMutex.lock();
                command = "";
                globalMutex.unlock();
            }

            if (command.compare("down")  == 0 )
            {
                rectangle.move(0,1*MOVE_SPEED*time.asSeconds());

                globalMutex.lock();
                command = "";
                globalMutex.unlock();
            }

            if (command.compare("right")  == 0 )
            {
                rectangle.move(1*MOVE_SPEED*time.asSeconds(),0);

                globalMutex.lock();
                command = "";
                globalMutex.unlock();
            }

            if (command.compare("up")  == 0 )
            {
                rectangle.move(0,-1*MOVE_SPEED*time.asSeconds());

                globalMutex.lock();
                command = "";
                globalMutex.unlock();
            }

        }


        window.draw( rectangle );
        window.display();
        window.clear();

        time = Clock.restart();
    }
}

void tcpSend()
{
        sf::Packet packetSend;
        globalMutex.lock();
        packetSend << command;
        globalMutex.unlock();
        command = "";
        socket.send(packetSend);
}

void udpSend()
{
}

void tcpServerListen()
{
    sf::TcpListener listener;
    listener.listen(PORT);
    listener.accept(socket);
    std::cout << "New client connected: " << socket.getRemoteAddress() << std::endl;
}

void udpServer()
{
}


void udpClient()
{
}


void tcpClient()
{
        if(socket.connect("127.0.0.1", PORT) == sf::Socket::Done)
                std::cout << "Connected\n";
    else
        std::cout << "FAILURE\n";

    while( !quit )
    {
                std::string msg;
                sf::Packet packetReceive;
                socket.receive(packetReceive);

                packetReceive >> msg;

                if( !msg.empty() )
                {
            std::cout << "Command Received: " << msg << std::endl;
            globalMutex.lock();
            command = msg;
            globalMutex.unlock();
                }
    }
}
 

[attachment deleted by admin]

2
[updated code, scroll down or click] http://en.sfml-dev.org/forums/index.php?topic=10363.msg72710#msg72710


Hi everyone.  I just started with SFML -- this is really my first project that involves graphics at all, mainframe coder here :P (nice green COBOL & Assembler).   

Right now I have moving eyes and blinking eyes.  Eventually, I want to move this to a more OO approach (face object contains eye objects, nose object etc) and an OO management of images.

Other than the lack of OO/image management class is there anything glaringly obvious that I'm doing wrong w/ SFML (like loading images into memory a million times or just doing something funny).  Tear it apart please, I'd like to find the areas I need to read up on more/study more =). 

Just a quick video so you have an idea of what it does so far... sorry for low frame rate -- cheap recording software.  "Action" starts at ~4sec
https://www.youtube.com/watch?v=j5GjC3NMTrs


I've attached the project source code -- not too many lines ~450 (which includes counting whitespace).  I figure would be easier to grab that then have  wall of sourcecode on the forum ;].


I think the area I'm most uncomfortable with is the way I handled the blink animation.

main.cpp fragment
    sf::RenderWindow window(sf::VideoMode(1024, 768), "SFML works!");
    window.setFramerateLimit(30);
 

main.cpp fragment
    /**************************************************************************/
    /*                         LOAD EYEBALL PART IMAGES                       */
    /**************************************************************************/
    if( !LeftEye.loadEyeLid("img/eyes/left/eyeball_lid.png") )
        return -1;
    if( !LeftEye.loadEyeLid("img/eyes/left/eyeball_lid_1.png") )
        return -1;
    if( !LeftEye.loadEyeLid("img/eyes/left/eyeball_lid_2.png") )
        return -1;
    if( !LeftEye.loadEyeLid("img/eyes/left/eyeball_lid_3.png") )
        return -1;
    LeftEye.finalizeLid();


    if( !LeftEye.loadEyeColor("img/eyes/left/eyeball_color.png") )
        return -1;
    if( !LeftEye.loadEyeWhite("img/eyes/left/eyeball_white.png") )
        return -1;
 


eye.cpp fragment
void Eye::drawEye()
{
    eye_bound.clear();
    eye_bound.draw(sprite_eye_white);
    eye_bound.draw(sprite_eye_color);

    if( !blinking ) // grab top eye lid
    {
        frame_counter = 0;
        sprite_eye_lid.setTexture(texture_eye_lid.front());
        eye_bound.draw(sprite_eye_lid);
    }
    else
    {
        frame_counter++;

        if( frame_counter > 15 )
            frame_counter = 0;

        if( frame_counter == 3 )
            sprite_eye_lid.setTexture(texture_eye_lid.at(1));
        else if( frame_counter == 6 )
            sprite_eye_lid.setTexture(texture_eye_lid.at(2));
        else if( frame_counter == 9 )
            sprite_eye_lid.setTexture(texture_eye_lid.at(3));
        else if( frame_counter == 12 )
            sprite_eye_lid.setTexture(texture_eye_lid.at(2));
        else if( frame_counter == 15 )
            sprite_eye_lid.setTexture(texture_eye_lid.at(1));
        else if( frame_counter == 0 )
        {
            sprite_eye_lid.setTexture(texture_eye_lid.at(0));
            blinking = false;
        }

        eye_bound.draw(sprite_eye_lid);
    }

    eye_bound.display();

    rendered_eye.setTexture(eye_bound.getTexture());
}
 

[attachment deleted by admin]

Pages: [1]
anything