[ create a new paste ] login | about

Link: http://codepad.org/qsznZjow    [ raw code | fork ]

C++, pasted on Jun 9:
#include "stdafx.h"
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Network.hpp>
#include <iostream>
using namespace std;
using sf::SocketUDP;
using sf::IPAddress;
using sf::Packet;

class Input
{
public:
	Input():
	  left(false), right(false), up(false), down(false)
	  {}
	bool left;
	bool right;
	bool up;
	bool down;
	void update(const sf::Input& input);
};

void Input::update(const sf::Input& input)
{
	left = input.IsKeyDown(sf::Key::Left);
	right = input.IsKeyDown(sf::Key::Right);
	up = input.IsKeyDown(sf::Key::Up);
	down = input.IsKeyDown(sf::Key::Down);
}

class Player
{
public:
	Player(float x, float y, float width, float height, float xSpeed, float ySpeed):
	  xPos(x), yPos(y), width(width), height(height), xSpeed(xSpeed), ySpeed(ySpeed)
	  {}
	Input input;
	float xPos;
	float yPos;
	float height;
	float width;
	float xSpeed;
	float ySpeed;
	void move(float delta);
	void draw(sf::RenderWindow & app);
};

void Player::draw(sf::RenderWindow & app)
{
	glBegin(GL_QUADS);
	glVertex2f(xPos, yPos);
	glVertex2f(xPos + width, yPos);
	glVertex2f(xPos + width, yPos + height);
	glVertex2f(xPos, yPos + height);
	glEnd();
}

void Player::move(float delta)
{
	int xDir = 0;
	int yDir = 0;
	if(input.left ^ input.right)
	{
		if(input.left)
			xDir = -1;
		else
			xDir = 1;
	}
	if(input.up ^ input.down)
	{
		if(input.up)
			yDir = 1;
		else
			yDir = -1;
	}
	xPos += xDir * xSpeed * delta;
	yPos += yDir * ySpeed * delta;
}

sf::Packet& operator>>(sf::Packet& packet, Input& inp)
{
	packet >> inp.left >> inp.right >> inp.up >> inp.down;
	return packet;
}

sf::Packet& operator<<(sf::Packet& packet, const Input& inp)
{
	packet << inp.left << inp.right << inp.up << inp.down;
	return packet;
}

class Game
{
public:
	Game();
	int run();
private:
	void handleEvents();
	void update(float delta);
	void updateGameState(float delta);
	void initNetwork();
	void receiveClientInput();
	void sendClientInput();
	void sendGameState();
	void receiveAndSyncGameState();

	Player myServerPlayer;
	Player myClientPlayer;
	bool myIsServer;
	bool myIsConnected;
	sf::IPAddress myIPAddress;
	sf::SocketUDP mySocket;
	sf::RenderWindow * myWindow;
	static const unsigned short PORT;
	static const float UPDATE_RATE;
};

const unsigned short Game::PORT = 3456;
const float Game::UPDATE_RATE = 1.f/100; //TODO different rates for update and networking

Game::Game():
myServerPlayer(-1, -1, 0.2f, 0.2f, 0.35f, 0.35f),
myClientPlayer(0.5f, 0.5f, 0.2f, 0.2f, 0.35f, 0.35f),
myIsServer(false),
myWindow(0),
myIsConnected(false)
{

}

void Game::initNetwork()
{
	while(true)
	{
		cout << "Server mode(s) or Client mode (c)? ";
		string str;
		cin >> str;
		if(str == "s")
		{
			myIsServer = true;
			break;
		}
		else if(str == "c")
		{
			myIsServer = false;
			break;
		}
	}
	if(!mySocket.Bind(PORT))
	{
		cerr << "Error binding socket to port << PORT";
	}
	cout << "Enter ip: ";
	string line;
	cin >> line;
	myIPAddress = IPAddress(line);
	mySocket.SetBlocking(false);
	myIsConnected = true;
}

void Game::handleEvents()
{
	sf::Event event;
	while (myWindow->GetEvent(event))
	{
		switch(event.Type)
		{
		case sf::Event::Closed:
			myWindow->Close();
			break;
		case sf::Event::Resized:
			glViewport(0, 0, event.Size.Width, event.Size.Height);
			break;
		default:
			break;
		}
	}
}

int Game::run()
{
	initNetwork();
	myWindow = new sf::RenderWindow(sf::VideoMode(800, 600, 32), "SFML Window");
	float restTime = 0;
	while(myWindow->IsOpened())
	{
		handleEvents();
		restTime += myWindow->GetFrameTime();
		while(restTime > UPDATE_RATE)
		{
			restTime -= UPDATE_RATE;
			update(UPDATE_RATE);
		}
		glClear(GL_COLOR_BUFFER_BIT);
		myClientPlayer.draw(*myWindow);
		myServerPlayer.draw(*myWindow);
		myWindow->Display();
	}
	return 0;
}

void Game::sendClientInput()
{
	sf::Packet toSend;
	toSend << myClientPlayer.input;
	unsigned short port = PORT;
	sf::Socket::Status status = mySocket.Send(toSend, myIPAddress, port);
	switch(status)
	{
	case sf::Socket::Disconnected:
		cout << "Disconnected" << endl;
		myIsConnected = false;
		break;
	case sf::Socket::Error:
		cout << "Error sending input" << endl;
		break;
	case sf::Socket::Done:
		break;
	case sf::Socket::NotReady:
		//try again next time;
		break;
	}
}

void Game::receiveClientInput()
{
	sf::Packet toReceive;
	unsigned short port = PORT;
	sf::Socket::Status status = mySocket.Receive(toReceive, myIPAddress, port);
	switch(status)
	{
	case sf::Socket::Disconnected:
		cout << "Disconnected" << endl;
		myIsConnected = false;
		break;
	case sf::Socket::Error:
		cout << "Error receiving" << endl;
		break;
	case sf::Socket::Done:
		toReceive >> myClientPlayer.input;
		break;
	case sf::Socket::NotReady:
		//try again next time;
		break;
	}
}

void Game::sendGameState()
{
	sf::Packet toSend;
	toSend << myServerPlayer.xPos << myServerPlayer.yPos << myServerPlayer.input
		<< myClientPlayer.xPos << myClientPlayer.yPos;
	sf::Socket::Status status = mySocket.Send(toSend, myIPAddress, PORT);
	switch(status)
	{
	case sf::Socket::Disconnected:
		cout << "Disconnected" << endl;
		myIsConnected = false;
		break;
	case sf::Socket::Error:
		cout << "Error sending" << endl;
		break;
	case sf::Socket::Done:
		break;
	case sf::Socket::NotReady:
		//try again next time;
		break;
	}
}

void Game::receiveAndSyncGameState()
{
	sf::Packet toReceive;
	unsigned short port = PORT;
	sf::Socket::Status status = mySocket.Receive(toReceive, myIPAddress, port);
	switch(status)
	{
	case sf::Socket::Disconnected:
		cout << "Disconnected" << endl;
		myIsConnected = false;
		break;
	case sf::Socket::Error:
		cout << "Error receiving game state" << endl;
		break;
	case sf::Socket::Done:
		toReceive >> myServerPlayer.xPos >> myServerPlayer.yPos >> myServerPlayer.input
		>> myClientPlayer.xPos >> myClientPlayer.yPos;
		//no interpolation yet
		break;
	case sf::Socket::NotReady:
		//try again next time;
		break;
	}
}

void Game::updateGameState(float delta)
{
	myClientPlayer.move(delta);
	myServerPlayer.move(delta);
}

void Game::update(float delta)
{
	if(myIsServer)
	{
		myServerPlayer.input.update(myWindow->GetInput());
		if(myIsConnected)
		{
			receiveClientInput();
			updateGameState(delta);
			sendGameState();
		}
	}
	else
	{
		myClientPlayer.input.update(myWindow->GetInput());
		if(myIsConnected)
		{
			sendClientInput();
			receiveAndSyncGameState();
		}
	}
}

int main()
{
	Game game;
	return game.run();
}


Create a new paste based on this one


Comments: