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.


Messages - Snikur

Pages: [1]
1
Network / Re: Sync player movement causes duplications
« on: March 06, 2014, 12:43:58 pm »
I found some example code online so I personally don't know what the difference between mutex is and not.
The problem with the screenshot is that it alter between frames so a screenshot will not be able to show the multiple position (same as when you circle the mouse the eye can see 8-10 pointers at the same time because of refresh rate).

I got it working though and the error was simply because both the client and server were sending the same data causing multiple inputs. I fixed it by simply telling the server to send ball position and right flipper while the client only sends information about the left one.

Heres my code for future reference, feel free to give me advice on how to make it better other than implement better ball logic and actually using headers, classes and functions :P

Oh, and another thing, I can't make a release static on the way the project is set up so I can't share my game with people that don't have visual studio installed on their pc. It do however work if I exclude network and audio for some reason. Any ideas?

#ifdef SFML_STATIC
#pragma comment(lib, "glew.lib")
#pragma comment(lib, "freetype.lib")
#pragma comment(lib, "jpeg.lib")
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "gdi32.lib")  
#endif // SFML_STATIC

#include <SFML/Graphics.hpp>
#include <cmath>
#include <iostream>
#include <ostream>
#include <fstream>
#include <sstream>
#include <SFML/Audio.hpp>
#include <SFML/Network.hpp>


const int FPS = 60, WINDOWWIDTH = 320, WINDOWHEIGHT = 180;
const unsigned short PORT = 5000;
const std::string IPADDRESS("123.456.789.1");
const float PI = 3.14159265359, shapeRadius = 5;
int score = 0;
int inputSend1 = 0, inputSend2 = 0;
bool serverPick = false;

sf::RenderWindow window(sf::VideoMode(WINDOWWIDTH, WINDOWHEIGHT), "Pong");
sf::Vector2f ballV, ballP, playerV, playerP, opponentP, inputSend3;
sf::CircleShape shape(shapeRadius);
sf::Texture brickTxt;
sf::Sprite brickSpr, opponentSpr, middleSpr;
sf::Event event;
sf::Font font1;
sf::Text scoreText;
sf::TcpSocket socket;
sf::Mutex globalMutex;
sf::SoundBuffer buffer;
sf::Sound sound;
void windowCloser(), sync(void), server(void), client(void);

//main
int main(int argc, char* argv[])
{
        if (!brickTxt.loadFromFile("resources/brick.png"));
        if (!font1.loadFromFile("resources/arial.ttf"));
        if (!buffer.loadFromFile("resources/jump.wav"));
        sound.setBuffer(buffer);
        sf::Thread* thread = 0;
        char who = 'a';

        while (who != 'S' && who != 'C')
        {
                std::cout << "Server or Client? S/C ";
                std::cin >> who;
                toupper(who);

                if (who == 'S')
                        server();
                if (who == 'C')
                        client();
        }

        brickSpr.setTexture(brickTxt);
        opponentSpr.setTexture(brickTxt);      
        middleSpr.setTexture(brickTxt);

        shape.setFillColor(sf::Color::White);
        ballP.x = WINDOWWIDTH/2;
        ballP.y = WINDOWHEIGHT/2;
        playerP.x = 0;
        playerP.y = WINDOWHEIGHT / 2;
        opponentP.x = WINDOWWIDTH - opponentSpr.getGlobalBounds().width;
        opponentP.y = WINDOWHEIGHT / 2;
        ballV.x = 3;
        ballV.y = 3;
        middleSpr.setScale(0.5, 6.7);
        middleSpr.setPosition(WINDOWWIDTH / 2, 0);

        thread = new sf::Thread(&sync);
        thread->launch();

        if (thread)
        {
                thread->wait();
                delete thread;
        }

        //main loop
        while (window.isOpen())
        {
                event;
                windowCloser();

                ballP.x = inputSend3.x + ballV.x;
                ballP.y = inputSend3.y + ballV.y;
                shape.setPosition(ballP.x, ballP.y);
                playerP.y = inputSend1;
                opponentP.y = inputSend2;

                playerP.y = playerP.y + playerV.y;
                opponentP.x = WINDOWWIDTH - opponentSpr.getGlobalBounds().width;
                brickSpr.setPosition(playerP.x, playerP.y);
                opponentSpr.setPosition(opponentP.x, opponentP.y);

                if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
                {
                        playerP.y -= 5;
                }

                if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
                {
                        playerP.y += 5;
                }


                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
                {
                        opponentP.y -= 5;
                }

                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
                {
                        opponentP.y += 5;
                }

                if (shape.getPosition().x < -10)
                {
                        score = 0;
                        ballV.x = -ballV.x;
                        ballP.x = (WINDOWWIDTH / 2);
                        ballP.y = (WINDOWHEIGHT / 2);
                }
                if (shape.getPosition().x > WINDOWWIDTH + 10)
                {
                        score = 0;
                        ballV.x = -ballV.x;
                        ballP.x = (WINDOWWIDTH / 2);
                        ballP.y = (WINDOWHEIGHT / 2);
                }

                if (shape.getPosition().y > (WINDOWHEIGHT-WINDOWHEIGHT))
                {
                        ballV.y = -ballV.y;
                }
                if (shape.getPosition().y < (WINDOWHEIGHT-shapeRadius*2))
                {
                        ballV.y = -ballV.y;
                }


                //collision

                if (brickSpr.getGlobalBounds().intersects(shape.getGlobalBounds()))
                {
                        sound.play();
                        ballP.x = 6;
                        ballV.x = -ballV.x;
                        score++;
                }

                if (opponentSpr.getGlobalBounds().intersects(shape.getGlobalBounds()))
                {
                        sound.play();
                        ballP.x = WINDOWWIDTH - 12;
                        ballV.x = -ballV.x;
                        score++;
                }

                std::ostringstream scoreString;
                scoreString << score;
                scoreText.setString(scoreString.str());
                scoreText.setFont(font1);
                scoreText.setColor(sf::Color::White);
                scoreText.setPosition((WINDOWWIDTH / 2)+10, 0);

                if (!serverPick)
                {
                        globalMutex.lock();
                        inputSend1 = playerP.y;
                        globalMutex.unlock();
                }

                if (serverPick)
                {
                        globalMutex.lock();
                        inputSend2 = opponentP.y;
                        inputSend3.x = ballP.x;
                        inputSend3.y = ballP.y;
                        globalMutex.unlock();
                }



                sync();
                window.clear();
                window.draw(shape);
                window.draw(brickSpr);
                window.draw(opponentSpr);
                window.draw(middleSpr);
                window.setFramerateLimit(FPS);
                window.draw(scoreText);
                window.display();
        }

        return 0;
}

void windowCloser()
{
        while (window.pollEvent(event))
        {
                if (event.type == sf::Event::Closed)
                        window.close();
        }
}

void sync(void)
{
        if (serverPick)
        {
                sf::Packet packetSend;
                globalMutex.lock();
                packetSend << inputSend3.x << inputSend3.y << inputSend2;
                globalMutex.unlock();
                socket.send(packetSend);

                sf::Packet packetReceive;
                socket.receive(packetReceive);
                packetReceive >> inputSend1;
        }


        if (!serverPick)
        {
                sf::Packet packetSend;
                globalMutex.lock();
                packetSend << inputSend1;
                globalMutex.unlock();
                socket.send(packetSend);

                sf::Packet packetReceive;
                socket.receive(packetReceive);
                packetReceive >> inputSend3.x >> inputSend3.y >> inputSend2;
        }
}

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

void client(void)
{
        if (socket.connect(IPADDRESS, PORT) == sf::Socket::Done)
        {
                std::cout << "\nConnected\n" << std::endl;
                serverPick = false;
        }
        else
        {
                std::cout << "Can't connect.";
        }
}

2
Network / Sync player movement causes duplications
« on: March 05, 2014, 11:27:06 pm »
I tried to make a simple Pong with 1 vs 1 over the local area network and it works just fine but it get slightly desynced after a while. It looks like 2 balls and 4 "flippers" or whatever I should call em.

Any ideas on how to sync the games better?

I've synchronized the two players and the ball.
I can't provide a screenshot as the game alter between frames, making it impossible for a camera or a monitor to actually capture it.

I'm fairly new to programming so any advice is appreciated.

Code:
                ballP.x = inputSend3.x + ballV.x; //ball position + velocity
                ballP.y = inputSend3.y + ballV.y; //ball position + velocity
                playerP.y = inputSend1; //player position
                opponentP.y = inputSend2; //player two position
//Changes values of player and opponent using arrowkeys and W/S.
        globalMutex.lock(); //sends values to sync
                inputSend1 = playerP.y;
                inputSend2 = opponentP.y;
                inputSend3.x = ballP.x;
                inputSend3.y = ballP.y;
                globalMutex.unlock();

        sync();

void sync(void)
{ //sync values between server and client
        sf::Packet packetSend;
        globalMutex.lock();
        packetSend << inputSend3.x << inputSend3.y << inputSend2 << inputSend1;
        globalMutex.unlock();
        socket.send(packetSend);

        sf::Packet packetReceive;
        socket.receive(packetReceive);
        packetReceive >> inputSend3.x >> inputSend3.y >> inputSend2 >> inputSend1;
}


 

Pages: [1]