2009-06-30 4 views
8

Я писал многопользовательскую игру в формате 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)]; 
     } 

Это, кажется, отлично работает. Чтобы учесть во внимание, сервер корректирует информацию клиента каждый раз, отправляя эти данные.

С этой системой очень мало полосы пропускания используется для обработки движения. Однако различия между моим сервером и его координатами и углами слишком велики. Должен ли я, возможно, расширить свой «алгоритм», чтобы также учитывать задержку, которую имеет пользователь? Или есть ли лучшие способы обработки движений в клиенте? <> серверные многопользовательские игры с отличной производительностью?

ответ

6

Моя первоначальная конструкция будет похожа на вашу, но если это не работает, возможно, вы можете позволить клиенту делать ВСЕ движение и просто иметь сервер для проверки диапазона.

Таким образом, если ваша последняя сообщенная позиция была X, следующая должна находиться в радиусе от X, где радиус основан на различии в метках времени, отправленных клиентом с данными x, y.

В основном это необходимо для обнаружения обмана.

Остановка, боевые действия и т. Д. Потребовали бы отправки позиции вместе с атакой, а действия, инициируемые позициями, были бы инициированы только после того, как клиент отправил обновление для этой позиции, но будет основан на сервере.

Не уверен, что это поможет слишком много, но это может остановить дрожащие ресинхроны, которые вы увидите из своего первоначального алгоритма.

Комментарий Ответ:

Нет, клиенты будут по-прежнему информирует сервер о своей позиции, но сервер не будет пытаться вычислить следующую позицию. Это означало бы, что сервер (и все остальные клиенты) будет по крайней мере одним циклом отправки/получения позади.

Я предполагаю, что я говорю, просто позвольте клиенту выполнить всю работу, выяснить, где находится персонаж, и сообщить серверу, но включить достаточно информации о том, что сервер может дополнительно проверить правильность, чтобы никто не обманывал.

Обнаружение читов даже может быть отключено для обеспечения производительности или установлено для случайной проверки.

Примечание: вся информация о столкновении/положении объектов в пределах диапазона перемещения должна быть отправлена ​​клиенту для этого.

+0

Не будет ли сервер продолжать получать и повторно отправлять тонны сообщений, если все клиенты должны были сообщить всем другим клиентам об их текущем местоположении? – Tom

+0

+1 Я действительно собирался предложить то же самое. Это то, что делают многие популярные многопользовательские видеоигры. Сервер просто гарантирует, что все синхронизируются периодически. (Я считаю, что игры Quake делают это.) –

+0

Ну, мой первый вопрос по-прежнему применяется. Разве клиенты не должны отправлять тысячи сообщений все время, чтобы обновлять сервер с каждым шагом? После этого сервер отправляет эти данные еще раз всем близлежащим игрокам. – Tom

0

Ваш сервер настолько медленный, что не может справиться со всем движением? Особенно в 2-й игре? Обычно, когда я делаю небольшие 2d-игры, сервер возвращает мне все мои движения, поэтому на клиенте не требуется никаких вычислений. Если сервер начинает отставать, я просто немного замерзаю, чего обычно ждут в любом случае (хотя этого почти никогда не бывает).

В любом случае, я бы определенно посмотрел, как производительность без того, чтобы клиент сам делал какие-либо фактические вычисления. Если производительность недостаточно хороша, см., Если задержка перемещения игроков на сервере вызывает задержку (и начать использовать другой поток для каждого клиента).

Если действительно существует ограничение в пропускной способности (сами перемещения передают очень мало данных), то, конечно же, вам нужно найти среднюю задержку этого конкретного пользователя и вычислить это в алгоритме. Тем не менее, чтобы постоянно находить среднее значение (для точности), вам придется продолжать пинговать сервер, чтобы найти время туда и обратно, что не должно быть дорогостоящим.

+0

Это не маленькая 2D-игра. Он должен одновременно обслуживать сотни игроков. Мне нужна максимально оптимизированная система. – Tom

+0

hmm, в этом случае настройка сервера так, чтобы он отправлял данные через достаточно малые промежутки времени. Конечно, всем серверам нужна какая-то игровая крышка, но, по крайней мере, добавьте 10-20 мс отставание на стороне движения клиента. Он едва заметен и должен в большинстве случаев соответствовать фактической позиции игроков. – AlbertoPL

1

Есть два способа, которые я могу придумать для этого: имейте команды выдачи клиента серверу &, сервер будет конечным хранителем карты.

Или держать карты в клиентах, & клиентов должны будут устанавливать соединения с другими клиентами они «ряд», чтобы сделать движение, с делопроизводством делаются сервер & проверяется несколько коллег (хакерская полиция).

Интересно, что у меня есть возможность отслеживать одноранговые соединения, а сверстники с задержкой выше определенного порога просто не появятся в игре.

+0

Интересно, но такие ограничения ограничивают большие бои, поскольку P2P не может одновременно обрабатывать множество подключений - теперь вы также полагаетесь на подключение клиента для других клиентов. Я все еще ищу лучшую клиентскую систему сервера <>. – Tom

+2

Почему P2P не может обрабатывать множество соединений? Каждый раз, когда кто-то что-то делает, вам либо требуется ретрансляция с сервера, либо сообщение от однорангового узла.Я думал, что трафик близок к тому же (я могу ошибаться). – ryansstack

Смежные вопросы