I've made a nice multi-client server game using Winsock however the movements are quite laggy. My current set-up is:
At regular intervals the server send out the
info of all clients to all the clients.
e.g coords, direction, state.
|
The clients receive the data and update their
own data and draw it.
|
On every key press and release the clients
send to the server data on which keys are
being pressed
|
The server uses the client keyboard information
to move the players and detect collisions and stuff
Obviously this leads to a bit of lag but what seems to happen is when you press
a key the character moves a bit then after a delay starts moving at at regular intervals as if the movement was in a WM_KEYDOWN case. Although this is the
problem I would mainly like replies on, general feedback is appreciated. I've uploaded some of the source code I believe is relevant;
---------Server---------
This is how it updates at regular intervals:
1 2 3 4 5 6
|
if (GetCurrentTime() - lfTime > 100/6)
{
for (int i = 0; i < playerVector.size(); i++) if (!playerVector[i].dead) playerVector[i].Calculate(i);
UpdateClient();
lfTime = GetCurrentTime();
}
|
The update client function:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
void UpdateClient()
{
for (unsigned int i = 0; i < playerVector.size(); i++)
{
std::stringstream stream;
stream << playerVector.size();
for (unsigned int j = 0; j < playerVector.size(); j++)
{
stream << "," << j << "," << playerVector[j].x << "," << playerVector[j].y << "," << playerVector[j].dir << "," << playerVector[j].dead << "|";
}
send(playerVector[i].socket, stream.str().c_str(), stream.str().length()+1, 0);
}
}
|
in FD_READ this is how it updates itself:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
void UpdateServer()
{
for(int n=0;n<=nMaxClients;n++)
{
char szIncoming[1024];
ZeroMemory(szIncoming,sizeof(szIncoming));
int inDataLength = recv(playerVector[n].socket,(char*)szIncoming, sizeof(szIncoming),0);
if(inDataLength!=-1)
{
char * comma1 = strchr(szIncoming,',');
int ID = atoi(szIncoming);
char *buffer = (comma1 + 1);
for(unsigned int i = 0; i < 256; i++) playerVector[ID].keys[i] = (buffer[i]=='1');
}
}
}
|
How it calculates movement:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
// Move
if (keys['W'] || keys[VK_UP])y += 1;
if (keys['S'] || keys[VK_DOWN]) y -= 1;
if (keys['A'] || keys[VK_LEFT])
{
x -= 2;
dir = 0;
}
if (keys['D'] || keys[VK_RIGHT])
{
x += 2;
dir = 1;
}
|
---------Client---------
When it updates the server on new key states:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
case WM_KEYDOWN:
{
keys[wParam] = true;
UpdateServer();
return 0;
}
case WM_KEYUP:
{
keys[wParam] = false;
UpdateServer();
return 0;
}
|
How it updates the server:
1 2 3 4 5 6 7
|
void UpdateServer()
{
std::stringstream stream;
stream << ID << ",";
for (int i = 0; i < 256; i++) stream << keys[i];
send(Socket, stream.str().c_str(), stream.str().length()+1, 0);
}
|
In FD_READ it updates itself like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
char * srlIncoming = szIncoming;
playerVector.resize(atoi(srlIncoming), Player());
for (unsigned int i = 0; i < playerVector.size(); i++)
{
char * comma1 = strchr(srlIncoming,',');
char * comma2 = strchr(comma1 + 1,',');
char * comma3 = strchr(comma2 + 1,',');
char * comma4 = strchr(comma3 + 1,',');
char * comma5 = strchr(comma4 + 1,',');
int n = atoi(comma1 + 1);
playerVector[n].id = n;
playerVector[n].x = atof(comma2 + 1);
playerVector[n].y = atof(comma3 + 1);
playerVector[n].dir = atof(comma4 + 1);
playerVector[n].dead = atof(comma5 + 1);
srlIncoming = strchr(srlIncoming,'|') + 1;
}
|
Thanks for taking the time to read this. If you need any more source just ask. On an unrelated not how would I deal with something like bullets in this set-up?
Thanks,
Rowan.