diff --git a/SConstruct b/SConstruct index e5d6822..09f87dd 100755 --- a/SConstruct +++ b/SConstruct @@ -36,7 +36,7 @@ SFML_VERSION = '2.0-rc' BIN_DIR = 'bin' CXX = 'g++' CC = 'gcc' -CXXFLAGS = ['-Wall', '-O2', '-g'] +CXXFLAGS = ['-Wall', '-O0', '-g'] LINKFLAGS = [] LIBS_client = [] LIBS_server = [] @@ -48,8 +48,8 @@ if 'SFML_PATH' in os.environ: LIBPATH = ['%s/lib' % SFML_PATH] CPPFLAGS = [] CPPFLAGS += map(lambda x: '-I' + x, find_dirs_under('src/common')) -CPPFLAGS_client = ['-I%s/include' % SFML_PATH, - '-DGL_INCLUDE_FILE=\\"GL3/gl3w.h\\"'] +CPPFLAGS += ['-I%s/include' % SFML_PATH] +CPPFLAGS_client = ['-DGL_INCLUDE_FILE=\\"GL3/gl3w.h\\"'] CPPFLAGS_client += map(lambda x: '-I' + x, find_dirs_under('src/client')) CPPFLAGS_server = map(lambda x: '-I' + x, find_dirs_under('src/server')) @@ -67,7 +67,7 @@ if platform == 'windows': else: LIBS_client += ['sfml-network', 'sfml-window', 'sfml-graphics', 'sfml-system', 'GL', 'GLU'] - LIBS_server += ['sfml-network'] + LIBS_server += ['sfml-system','sfml-network'] LINKFLAGS.append('-Wl,-R%s/lib' % SFML_PATH) # our sources diff --git a/src/client/Client.cc b/src/client/Client.cc index 7cfdad4..a3e9a6e 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -1,11 +1,21 @@ #include #include "Client.h" +#include "Types.h" Client::Client() { + m_net_client = new Network(); + m_net_client->Create(59243, "127.0.0.1"); // Just connect to local host for now - testing + client_has_focus = true; } +Client::~Client() +{ + m_net_client->Destroy(); +} + + void Client::run(bool fullscreen, int width, int height) { if (!create_window(fullscreen, width, height)) @@ -22,6 +32,7 @@ void Client::run(bool fullscreen, int width, int height) double current_time = m_clock.getElapsedTime().asSeconds(); double elapsed_time = current_time - last_time; sf::Event event; + while (m_window->pollEvent(event)) { switch (event.type) @@ -42,6 +53,12 @@ void Client::run(bool fullscreen, int width, int height) case sf::Event::Resized: resize_window(event.size.width, event.size.height); break; + case sf::Event::LostFocus: + client_has_focus = false; + break; + case sf::Event::GainedFocus: + client_has_focus = true; + break; default: break; } @@ -50,37 +67,88 @@ void Client::run(bool fullscreen, int width, int height) update(elapsed_time); redraw(); last_time = current_time; + + // temporary for now. otherwise this thread consumed way too processing + sf::sleep(sf::seconds(0.005)); // 5 milli-seconds } } void Client::update(double elapsed_time) { - const double move_speed = 75.0; + static sf::Uint8 w_pressed_prev = KEY_NOT_PRESSED; + static sf::Uint8 a_pressed_prev = KEY_NOT_PRESSED; + static sf::Uint8 s_pressed_prev = KEY_NOT_PRESSED; + static sf::Uint8 d_pressed_prev = KEY_NOT_PRESSED; + static sf::Int32 rel_mouse_movement_prev = 0; + + sf::Packet client_packet; + + m_net_client->Receive(); + client_packet.clear(); + if(m_net_client->getData(client_packet)) + { + // Update player position as calculated from the server. + client_packet >> m_player->direction; + client_packet >> m_player->x; + client_packet >> m_player->y; + } + + // For now, we are going to do a very crude shove data into + // packet from keyboard and mouse events. + // TODO: Clean this up and make it more robust + client_packet.clear(); + + sf::Uint8 w_pressed = KEY_NOT_PRESSED; + sf::Uint8 a_pressed = KEY_NOT_PRESSED; + sf::Uint8 s_pressed = KEY_NOT_PRESSED; + sf::Uint8 d_pressed = KEY_NOT_PRESSED; + sf::Int32 rel_mouse_movement = 0; if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { - double direction = m_player->direction + M_PI_2; - m_player->x += cos(direction) * move_speed * elapsed_time; - m_player->y += sin(direction) * move_speed * elapsed_time; + a_pressed = KEY_PRESSED; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { - double direction = m_player->direction - M_PI_2; - m_player->x += cos(direction) * move_speed * elapsed_time; - m_player->y += sin(direction) * move_speed * elapsed_time; + d_pressed = KEY_PRESSED; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { - double direction = m_player->direction; - m_player->x += cos(direction) * move_speed * elapsed_time; - m_player->y += sin(direction) * move_speed * elapsed_time; + w_pressed = KEY_PRESSED; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { - double direction = m_player->direction + M_PI; - m_player->x += cos(direction) * move_speed * elapsed_time; - m_player->y += sin(direction) * move_speed * elapsed_time; + s_pressed = KEY_PRESSED; } - int xrel = sf::Mouse::getPosition(*m_window).x - m_width / 2; - sf::Mouse::setPosition(sf::Vector2i(m_width / 2, m_height / 2), *m_window); - m_player->direction -= M_PI * 0.5 * xrel / 1000; + rel_mouse_movement = sf::Mouse::getPosition(*m_window).x - m_width / 2; + + // This is a fix so that the mouse will not move outside the window and + // cause the user to click on another program. + // Note: Does not work well with fast movement. + if(client_has_focus) + { + sf::Mouse::setPosition(sf::Vector2i(m_width / 2, m_height / 2), *m_window); + } + + // Send an update to the server if something has changed + if((w_pressed_prev != w_pressed) || + (a_pressed_prev != a_pressed) || + (s_pressed_prev != s_pressed) || + (d_pressed_prev != d_pressed) || + (rel_mouse_movement_prev != rel_mouse_movement)) + { + client_packet << w_pressed; + client_packet << a_pressed; + client_packet << s_pressed; + client_packet << d_pressed; + client_packet << rel_mouse_movement; + + m_net_client->sendData(client_packet); + + w_pressed_prev = w_pressed; + a_pressed_prev = a_pressed; + s_pressed_prev = s_pressed; + d_pressed_prev = d_pressed; + rel_mouse_movement_prev = rel_mouse_movement; + } + m_net_client->Transmit(); } diff --git a/src/client/Client.h b/src/client/Client.h index e24c144..7f4a659 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -10,11 +10,13 @@ #include "WFObj.h" #include "GLMatrix.h" #include "GLBuffer.h" +#include "Network.h" class Client { public: Client(); + ~Client(); void run(bool fullscreen, int width, int height); protected: bool create_window(bool fullscreen, int width, int height); @@ -39,6 +41,8 @@ class Client GLMatrix m_modelview; GLBuffer m_overlay_hex_attributes; GLBuffer m_overlay_hex_indices; + refptr m_net_client; + bool client_has_focus; }; #endif diff --git a/src/common/Network.cc b/src/common/Network.cc new file mode 100644 index 0000000..71b5ad6 --- /dev/null +++ b/src/common/Network.cc @@ -0,0 +1,403 @@ +#include "Network.h" +#include "Timer.h" +#include +#include +#include + + +sf::Uint16 Network::numclients; +sf::UdpSocket Network::net_socket; +char Network::rxbuff[RECEIVE_BUFFER_SIZE]; +std::map Network::transmit_queue; +Client_t Network::clients[MAX_NUM_CLIENTS]; +sf::Clock Network::message_timer; + +sf::Uint32 Network::getUniqueMessageId( void ) +{ + sf::Uint32 next_msg_uid = 0; + while(transmit_queue.find(next_msg_uid) != transmit_queue.end()) + { + next_msg_uid++; + } + return next_msg_uid; +} + +void Network::Create(sf::Uint16 port, sf::IpAddress address ) +{ + sf::Uint16 current_client = 0; + Client_t tmpclient; + + Reset(); + + if(sf::IpAddress::None != address) + { + tmpclient.addr = address; + tmpclient.port = port; + numclients = addClients(&tmpclient, ¤t_client); + + net_socket.bind( sf::Socket::AnyPort ); + net_socket.setBlocking(false); + } + else + { + net_socket.bind( port ); + net_socket.setBlocking(false); + } +} + +void Network::Destroy( void ) +{ + /* Clean and exit */ + net_socket.unbind(); +} + +bool Network::getData(sf::Packet& p) +{ + bool rtn = false; + sf::Uint16 curcl; + + // Recurse through the client array and return if there is any + // received data for a given client + for(curcl = 0; curcl < numclients; (curcl)++) + { + if(!clients[curcl].receive.empty()) + { + p = clients[curcl].receive.front(); + clients[curcl].receive.pop(); + rtn = true; + break; + } + } + + + return rtn; +} + +bool Network::queueTransmitMessage(Network_Messages_T msg_type , sf::Packet p, Client_t * dest) +{ + sf::Packet packet; + sf::Uint8 type = (sf::Uint8)msg_type; + sf::Uint32 uid = UNIQUE_ID; + sf::Uint32 msg_id = getUniqueMessageId(); + Transmit_Message_t* message = new Transmit_Message_t(); + + // Add this to the list of packets expecting a response + packet << uid; + packet << type; + packet << msg_id; + packet.append(p.getData(), p.getDataSize()); + + message->msg_type = msg_type; + message->Data = packet; + message->TimeStarted = 0.0; + message->dest = dest; + + transmit_queue[msg_id] = message; + + return true; +} + +bool Network::sendData(sf::Packet& p, bool guaranteed) +{ + Network_Messages_T message_type = NETWORK_NORMAL; + if(guaranteed) + { + message_type = NETWORK_GUARANTEED; + } + + queueTransmitMessage(message_type, p); + + return true; +} + +int Network::addClients(Client_t *client, sf::Uint16 *curcl) +{ + int i; + int nc = -1; + for(i=0;iaddr) && (clients[i].port == client->port)) + { + nc = i; + } + else if((clients[i].addr == sf::IpAddress::None) && (clients[i].port == 0)) + { + break; + } + } + // Make sure to set the current client location, otherwise + // bad stuffs can happen. + if(nc == -1) + { + clients[i].addr = client->addr; + clients[i].port = client->port; + *curcl = i; + i++; + } + else + { + *curcl = nc; + } + return i; +} + +int Network::findClient(Client_t *client) +{ + int client_ndx; + for(client_ndx = 0; client_ndx < MAX_NUM_CLIENTS; client_ndx++) + { + if((clients[client_ndx].addr == client->addr) && (clients[client_ndx].port == client->port)) + { + break; + } + } + return client_ndx; +} + + +void Network::Receive() +{ + // Get any received packets + sf::IpAddress sender; + Client_t tmpclient; + sf::Uint16 curcl; + sf::Packet receive_packet; + receive_packet.clear(); + + // Receive any packets from the server + while(net_socket.receive(receive_packet, tmpclient.addr, tmpclient.port) == sf::Socket::Done) + { + sf::Uint32 uid; + receive_packet >> uid; + if(uid == UNIQUE_ID) + { + sf::Uint8 message_type; + sf::Uint32 msg_id; + receive_packet >> message_type; + receive_packet >> msg_id; + + numclients = addClients(&tmpclient, &curcl); + + switch((Network_Messages_T)message_type) + { + case NETWORK_CONNECT: + { + break; + } + case NETWORK_DISCONNECT: + { + break; + } + case NETWORK_ACK: + { + sf::Uint32 client_id = findClient(&tmpclient); + receive_packet >> message_type; + receive_packet >> msg_id; + + switch(message_type) + { + // Handle an acknowledged ping message + case NETWORK_PING: + { + if(MAX_NUM_CLIENTS > client_id) + { + clients[client_id].ping = Timer::GetTimeDouble() - transmit_queue[msg_id]->TimeStarted; + } + break; + } + // Handle an acknowledged guaranteed message + case NETWORK_GUARANTEED: + { + // Set that the message was acknowledged by the client + if(MAX_NUM_CLIENTS > client_id) + { + transmit_queue[msg_id]->Responses[&clients[client_id]] = Timer::GetTimeDouble(); + } + break; + } + + default: + break; // What the heck happened? + } + break; + } + case NETWORK_PING: + { + // Send a response indicating that ping was received + sf::Packet response; + response.clear(); + response << message_type << msg_id; + queueTransmitMessage(NETWORK_ACK, response, &(clients[curcl])); + break; + } + + case NETWORK_NORMAL: + { + // Handle any remaining data in the packet + clients[curcl].receive.push(receive_packet); + break; + } + + case NETWORK_GUARANTEED: + { + // Send a response indicating that the message was received + sf::Packet response; + clients[curcl].receive.push(receive_packet); + response.clear(); + response << message_type << msg_id; + queueTransmitMessage(NETWORK_ACK, response, &(clients[curcl])); + break; + } + + // Nothing to do + default: + break; + } + } + } +} + +void Network::Transmit() +{ + // Broadcast the mesages to all clients + sf::Uint32 msg_id = 0; + static double ping_timer = Timer::GetTimeDouble(); + + // Once per second, send ping messages ( just for fun ) + if((Timer::GetTimeDouble() - ping_timer) > 1000.0) + { + ping_timer = Timer::GetTimeDouble(); + sf::Packet response; + response.clear(); + queueTransmitMessage(NETWORK_PING, response); + } + + // Send any pending messages + while(transmit_queue.find(msg_id) != transmit_queue.end()) + { + double curTime = Timer::GetTimeDouble(); + Transmit_Message_t * message = transmit_queue[msg_id]; + switch(message->msg_type) + { + case NETWORK_PING: + case NETWORK_GUARANTEED: + { + // If the message has not yet been sent + // send the message and update the sent times. + if(0.0 == message->TimeStarted) + { + message->TimeStarted = Timer::GetTimeDouble(); + for(int i = 0; i < MAX_NUM_CLIENTS; i++) + { + if((clients[i].addr != sf::IpAddress::None) && (clients[i].port != 0)) + { + message->ClientTimeSent[&clients[i]] = message->TimeStarted; + net_socket.send(message->Data, clients[i].addr, clients[i].port); + } + } + } + else + { + // Message has already been sent, check to see if a response has been received + // if not, send another request after retry timer expired. + if(message->ClientTimeSent.size() > message->Responses.size()) + { + // Look for any clients that haven't responded + for ( std::map::iterator iter = message->ClientTimeSent.begin(); iter != message->ClientTimeSent.end(); ++iter ) + { + // Determine if enough time has elapsed to try and re-send + if((curTime - iter->second) >= 0.5) + { + // Determine if a response was already received from this client + if(message->Responses.find(iter->first) == message->Responses.end()) + { + // Resend the message to the client + net_socket.send(message->Data, iter->first->addr, iter->first->port); + message->ClientTimeSent[iter->first] = curTime; + } + } + } + } + else + { + // All clients have received the message, so remove it from the list + delete message; + transmit_queue.erase(transmit_queue.find(msg_id)); + } + } + break; + } + + // When sending an ACK, we only need to send the ACK to the sender. + case NETWORK_ACK: + { + if(NULL != message->dest) + { + net_socket.send(message->Data, message->dest->addr, message->dest->port); + } + // Transmitted the message, so remove it from the list + delete message; + transmit_queue.erase(transmit_queue.find(msg_id)); + break; + } + + default: + { + // A normal message, no response needed + // just send to all clients, then delete the message + for(int i=0;iData, clients[i].addr, clients[i].port); + } + delete message; + transmit_queue.erase(transmit_queue.find(msg_id)); + break; + } + } + msg_id++; + } +} + +int Network::getNumConnected( void ) +{ + return numclients; +} + +void Network::Reset() +{ + numclients = 0; + for(int i = 0; i < MAX_NUM_CLIENTS; i++) + { + clients[i].addr = sf::IpAddress(); + clients[i].port = 0; + while(!clients[i].receive.empty()) + { + clients[i].receive.pop(); + } + } + + sf::Uint32 next_msg_uid = 0; + while(transmit_queue.find(next_msg_uid) != transmit_queue.end()) + { + delete transmit_queue[next_msg_uid]; + next_msg_uid++; + } + + transmit_queue.clear(); + + message_timer.restart(); +} + +sf::Packet& operator <<(sf::Packet& Packet, const Network_Messages_T& NMT) +{ + sf::Uint8 net_msg_t = (sf::Uint8)NMT; + return Packet << net_msg_t; +} + +sf::Packet& operator >>(sf::Packet& Packet, Network_Messages_T& NMT) +{ + sf::Uint8 net_msg_t; + Packet >> net_msg_t; + NMT = (Network_Messages_T)net_msg_t; + return Packet; +} diff --git a/src/common/Network.h b/src/common/Network.h new file mode 100644 index 0000000..9369762 --- /dev/null +++ b/src/common/Network.h @@ -0,0 +1,96 @@ +#ifndef _NETWORK_HPP +#define _NETWORK_HPP + +#include +#include +#include +#include +#include +#include + +#define MAX_NUM_CLIENTS 8 +#define MAX_NUM_TUBES 4 + +#define UNIQUE_ID 0xDEADBEEF +#define RECEIVE_BUFFER_SIZE 1024 + +// In milliseconds +#define NETWORK_TIMEOUT 5000 + + + +// The bit indicating if the message requires a response +#define MSG_REQUIRES_RESPONSE_BIT ((sf::Uint16)1 << 15) + +// The bit indicating if the message is a transmission or a response +#define MSG_TX_BIT ((sf::Uint16)1 << 14) + +typedef enum{ + NETWORK_NONE, + NETWORK_CONNECT, + NETWORK_DISCONNECT, + NETWORK_ACK, + NETWORK_PING, + NETWORK_NORMAL, + NETWORK_GUARANTEED +}Network_Messages_T; + + +typedef struct{ + sf::IpAddress addr; + unsigned short port; + double ping; + std::queue receive; +}Client_t; + +typedef struct{ + // The packet + sf::Packet Data; + + // The type of message that is to be sent. + Network_Messages_T msg_type; + + // Destination client for an ACK message + // Perhaps later I will enable the ability to only send updates + // to specific clients. + Client_t * dest; + + // The time at which the message was origionally sent + double TimeStarted; + + // The time at which the message was last sent to each client + std::map ClientTimeSent; + + // The time at which a response was received from each client + std::map Responses; +} Transmit_Message_t; + +class Network{ + private: + static sf::Uint16 numclients; + static sf::UdpSocket net_socket; + static std::map transmit_queue; + static char rxbuff[RECEIVE_BUFFER_SIZE]; + static sf::Clock message_timer; + static sf::Uint32 getUniqueMessageId( void ); + static int addClients(Client_t *client, sf::Uint16 *curcl); + static int findClient(Client_t *client); + static bool queueTransmitMessage(Network_Messages_T msg_type , sf::Packet p, Client_t * dest = NULL); + + public: + static Client_t clients[MAX_NUM_CLIENTS]; + static void Create( sf::Uint16 port, sf::IpAddress address ); + static void Destroy( void ); + static bool getData(sf::Packet& p); + static bool sendData(sf::Packet& p, bool guaranteed = false); + static int getNumConnected( void ); + static void Transmit(); + static void Receive(); + static void Reset(); +}; + +sf::Packet& operator <<(sf::Packet& Packet, const Network_Messages_T& NMT); + +sf::Packet& operator >>(sf::Packet& Packet, Network_Messages_T& NMT); + +#endif diff --git a/src/common/Timer.cc b/src/common/Timer.cc new file mode 100644 index 0000000..b5e5137 --- /dev/null +++ b/src/common/Timer.cc @@ -0,0 +1,60 @@ +#include "Timer.h" + +// The number of time steps per second +const float STEPS_PER_SECOND = 60.0f; + +double Timer::totalElapsedTime; +float Timer::stepTime; +sf::Uint32 Timer::curTimeStep; + +void Timer::Init(void) +{ + // Reset the clock + myClock.restart(); + + // Set the time keepers to zero + myTotalElapsedTime = 0; + + // Reset the game speed + gameSpeed = 1.0f; +} + +void Timer::Update(void) +{ + // Record the time step + stepTime = ((myClock.getElapsedTime().asSeconds() / 1000.0f) * gameSpeed); + //stepTime = ((((sf::Window*)screen)->GetFrameTime() / 1000.0f) * gameSpeed); + myClock.restart(); + + // Add the time to the total time + myTotalElapsedTime += stepTime; + totalElapsedTime = myTotalElapsedTime; + + // Calculate the game step + curTimeStep = (sf::Uint32)(totalElapsedTime * STEPS_PER_SECOND); +} + +sf::Uint32 Timer::GetTime(void) +{ + return curTimeStep; +} + +float Timer::GetStepTime(void) +{ + return stepTime; +} + +sf::Uint32 Timer::GetTotalTime(void) +{ + return (sf::Uint32)(totalElapsedTime * 1000.0f); +} + +double Timer::GetTimeDouble(void) +{ + return totalElapsedTime; +} + +float Timer::GetElapsedTime(sf::Uint32 baseTime) +{ + return (totalElapsedTime - ((double)baseTime / STEPS_PER_SECOND)); +} diff --git a/src/common/Timer.h b/src/common/Timer.h new file mode 100644 index 0000000..7a0810b --- /dev/null +++ b/src/common/Timer.h @@ -0,0 +1,50 @@ +#ifndef _TIMER_H +#define _TIMER_H + +#include + + +class Timer +{ +public: + // Initializes the time module + void Init(void); + + // Updates the time module + void Update(); + + // Returns the current time step + static sf::Uint32 GetTime(void); + + // Returns the time that elapsed this step + static float GetStepTime(void); + + // Returns the total time elapsed in milliseconds + static sf::Uint32 GetTotalTime(void); + + // Returns the total time in seconds as a double + static double GetTimeDouble(void); + + // Returns the difference between the current time and the given time in seconds + static float GetElapsedTime(sf::Uint32 baseTime); + +private: + // The clock used to take the time measurements + sf::Clock myClock; + + // The game speed + float gameSpeed; + + // The total elapsed time since the start of the game + double myTotalElapsedTime; + + // The total elapsed time since the start of the game + static double totalElapsedTime; + + // The time that elapsed this step + static float stepTime; + + // The number of time steps since the start of the game + static sf::Uint32 curTimeStep; +}; +#endif diff --git a/src/common/Types.h b/src/common/Types.h new file mode 100644 index 0000000..215e744 --- /dev/null +++ b/src/common/Types.h @@ -0,0 +1,9 @@ +#ifndef TYPES_H +#define TYPES_H + +#define KEY_PRESSED 0xA5u +#define KEY_NOT_PRESSED 0x5Au + + + +#endif diff --git a/src/server/Server.cc b/src/server/Server.cc new file mode 100644 index 0000000..8950fcf --- /dev/null +++ b/src/server/Server.cc @@ -0,0 +1,103 @@ +#include "Server.h" +#include "Types.h" +#include + +Server::Server(sf::Uint16 port) +{ + m_net_server = new Network(); + m_net_server->Create(port, sf::IpAddress::None); + m_player = new Player(); + m_player->x = 0; + m_player->y = 0; + m_player->direction = M_PI_2; +} + +Server::~Server() +{ + m_net_server->Destroy(); +} + +void Server::run( void ) +{ + double current_time; + double elapsed_time; + double last_time = 0.0; + while(1) + { + current_time = m_clock.getElapsedTime().asSeconds(); + elapsed_time = current_time - last_time; + update( elapsed_time ); + last_time = current_time; + + // temporary for now. otherwise this thread consumed way too processing + sf::sleep(sf::seconds(0.005)); // 5 milli-seconds + } +} + + +void Server::update( double elapsed_time ) +{ + static Player player_prev; + const double move_speed = 75.0; + sf::Packet server_packet; + static sf::Uint8 w_pressed = KEY_NOT_PRESSED; + static sf::Uint8 a_pressed = KEY_NOT_PRESSED; + static sf::Uint8 s_pressed = KEY_NOT_PRESSED; + static sf::Uint8 d_pressed = KEY_NOT_PRESSED; + static sf::Int32 rel_mouse_movement = 0; + + m_net_server->Receive(); + if(m_net_server->getData(server_packet)) + { + server_packet >> w_pressed; + server_packet >> a_pressed; + server_packet >> s_pressed; + server_packet >> d_pressed; + server_packet >> rel_mouse_movement; + } + + if (KEY_PRESSED == a_pressed) + { + double direction = m_player->direction + M_PI_2; + m_player->x += cos(direction) * move_speed * elapsed_time; + m_player->y += sin(direction) * move_speed * elapsed_time; + } + if (KEY_PRESSED == d_pressed) + { + double direction = m_player->direction - M_PI_2; + m_player->x += cos(direction) * move_speed * elapsed_time; + m_player->y += sin(direction) * move_speed * elapsed_time; + } + if (KEY_PRESSED == w_pressed) + { + double direction = m_player->direction; + m_player->x += cos(direction) * move_speed * elapsed_time; + m_player->y += sin(direction) * move_speed * elapsed_time; + } + if (KEY_PRESSED == s_pressed) + { + double direction = m_player->direction + M_PI; + m_player->x += cos(direction) * move_speed * elapsed_time; + m_player->y += sin(direction) * move_speed * elapsed_time; + } + m_player->direction -= M_PI * 0.5 * rel_mouse_movement / 1000; + + server_packet.clear(); + + // Send the player update if there were changes + if((player_prev.direction != m_player->direction) || + (player_prev.x != m_player->x) || + (player_prev.y != m_player->y)) + { + server_packet << m_player->direction; + server_packet << m_player->x; + server_packet << m_player->y; + m_net_server->sendData(server_packet); + + player_prev.direction = m_player->direction; + player_prev.x = m_player->x; + player_prev.y = m_player->y; + } + + m_net_server->Transmit(); +} diff --git a/src/server/Server.h b/src/server/Server.h new file mode 100644 index 0000000..5812a06 --- /dev/null +++ b/src/server/Server.h @@ -0,0 +1,16 @@ +#include "Network.h" +#include "Player.h" +#include "refptr.h" + +class Server{ + public: + Server(sf::Uint16 port); + ~Server(); + void run( void ); + + protected: + void update(double elapsed_time); + refptr m_net_server; + refptr m_player; + sf::Clock m_clock; +}; diff --git a/src/server/main.cc b/src/server/main.cc index df10f86..71e6dbe 100644 --- a/src/server/main.cc +++ b/src/server/main.cc @@ -1,6 +1,6 @@ - #include #include +#include "Server.h" int main(int argc, char *argv[]) { @@ -24,12 +24,9 @@ int main(int argc, char *argv[]) } } - /* TODO: make this work... */ -#if 0 Server server(port); server.run(); -#endif return 0; }