Я писал многопользовательскую игру в формате 2D flash и сервер сокетов. Мой первоначальный план для алгоритма движения между клиентом и сервером был следующим:Движение «алгоритм» в клиент-серверном многопользовательском режиме (MMO)?
- клиент информирует сервер о режиме движения игрока (перемещение вперед или не двигается) и режим поворота игрока (не вращается, поворачивает налево или поворот направо) всякий раз, когда они меняются.
- Сервер зацикливает всех игроков каждые несколько миллисекунд и вычисляет угол поворота и перемещение расстояния в зависимости от разницы во времени. Тот же расчет выполняется клиентом.
Мой текущий расчет для клиента (то же математика используется в сервере) ==>
Turning
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)];
}
Это, кажется, отлично работает. Чтобы учесть во внимание, сервер корректирует информацию клиента каждый раз, отправляя эти данные.
С этой системой очень мало полосы пропускания используется для обработки движения. Однако различия между моим сервером и его координатами и углами слишком велики. Должен ли я, возможно, расширить свой «алгоритм», чтобы также учитывать задержку, которую имеет пользователь? Или есть ли лучшие способы обработки движений в клиенте? <> серверные многопользовательские игры с отличной производительностью?
Не будет ли сервер продолжать получать и повторно отправлять тонны сообщений, если все клиенты должны были сообщить всем другим клиентам об их текущем местоположении? – Tom
+1 Я действительно собирался предложить то же самое. Это то, что делают многие популярные многопользовательские видеоигры. Сервер просто гарантирует, что все синхронизируются периодически. (Я считаю, что игры Quake делают это.) –
Ну, мой первый вопрос по-прежнему применяется. Разве клиенты не должны отправлять тысячи сообщений все время, чтобы обновлять сервер с каждым шагом? После этого сервер отправляет эти данные еще раз всем близлежащим игрокам. – Tom