Я писал двухмерную многопользовательскую флеш-игру и сервер сокетов. Мой первоначальный план алгоритма движения между клиентом и сервером был следующим:
- The client informs the server about the player's movement mode (moving forward or not moving) and the player's turning mode (not turning, turning left or turning right) whenever these change.
- The server loops all players every few milliseconds and calculates the angle turned and distance moved, based on the difference in time. The same calculation is done by the client.
Мой текущий расчет для клиента (та же математика используется на сервере) ==>
Поворот
var newTimeStamp:uint = UtilLib.getTimeStamp(); //set current timeStamp
var rot:uint = Math.round((newTimeStamp - turningTimeStamp) / 1000 * 90); //speed = x degrees turning every 1 second
turningTimeStamp = newTimeStamp; //update timeStamp
if (turningMode == 1) //left
{
movementAngle = fixAngle(movementAngle - rot);
}
else if (turningMode == 2) //right
{
movementAngle = fixAngle(movementAngle + rot);
}
private function fixAngle(angle:int):uint //fixes an angle in degrees (365 -> 5, -5 -> 355, etc.)
{
if (angle > 360)
{
angle -= (Math.round(angle / 360) * 360);
}
else if (angle < 0)
{
angle += (Math.round(Math.abs(angle) / 360) + 1) * 360;
}
return angle;
}
Движение
var newTimeStamp:uint = UtilLib.getTimeStamp(); //set current timeStamp
var distance:uint = Math.round((newTimeStamp - movementTimeStamp) / 1000 * 300); //speed = x pixels forward every 1 second
movementTimeStamp = newTimeStamp; //update old timeStamp
var diagonalChange:Array = getDiagonalChange(movementAngle, distance); //with the current angle, howmuch is dX and dY?
x += diagonalChange[0];
y += diagonalChange[1];
private function getDiagonalChange(angle:uint, distance:uint):Array
{
var rAngle:Number = angle * Math.PI/180;
return [Math.round(Math.sin(rAngle) * distance), Math.round((Math.cos(rAngle) * distance) * -1)];
}
Кажется, это отлично работает. Чтобы учесть задержку, сервер время от времени корректирует информацию о клиенте, отправляя эти данные.
В этой системе очень мало пропускной способности используется для управления движением. Однако разница между координатами и углами моего сервера и клиента слишком велика. Должен ли я расширить свой «алгоритм», чтобы также учитывать задержку, которую имеет пользователь? Или есть лучшие способы управления движением в клиент-серверных многопользовательских играх с высокой производительностью?