Простая онлайн-игра в понг с синхронизацией по сети - PullRequest
5 голосов
/ 17 января 2011

Я пишу простую онлайн-игру-понг для двух игроков, играющих по сети.Это клиент-серверное приложение с игровой логикой на стороне сервера.У меня есть некоторые проблемы с синхронизацией игр на стороне клиента, и результат довольно неудовлетворительный.Вот как это работает в настоящее время:

  1. На стороне сервера у меня есть игровой объект, в котором хранится позиция игроков и мяча, каждый объект имеет свою позицию x, y и скорость x, y.,На основании этого положение объектов обновляется в цикле.На стороне клиента есть тот же локальный объект с теми же данными, и он также обновляется в цикле.
  2. Когда игрок нажимает / отпускает вверх или вниз, клиент отправляет сетевой пакет с одним целым числом, так чтоИгровой объект начинает / останавливает движение в игровом объекте на сервере.
  3. Сервер отправляет пакет синхронизации каждые 50 миллисекунд с позицией и скоростью всех трех объектов.Когда клиент получает этот пакет, он соответственно меняет позиции игровых объектов.

Этот метод работает не очень хорошо, так как он перемещает игровые объекты вперед и назад на стороне клиента.Есть идеи как его улучшить?

1 Ответ

17 голосов
/ 31 января 2011

Допустим, у вас задержка 30 мс между клиентом и сервером.Клиент посылает сообщение «Я хочу переместить мою ракетку вниз», и его ракетка имеет скорость y = 100 пикселей со скоростью 0,1 пикселя / мс

30 мсек спустя:

  • клиентская ракетка находится наy = 100 + 30 * 0.1 = 103px
  • сервер получает заказ от клиента и начинает перемещать ракетку (которая в настоящее время все еще находится в точке y = 100px на стороне сервера)

20 секунд спустя:

  • клиентская ракетка находится в точке y = 103 + 20 * 0.1 = 105px
  • клиентская ракетка на стороне сервера находится в точке y = 100 + 20 * 0,1 = 102px
  • сервер отправляет клиенту новую позицию (102px)

30 мсек спустя:

  • клиентская ракетка имеет значение y = 105 + 30 * 0.1 = 108px
  • клиент получает от сервера новое положение ракетки: 102px

В этот момент клиентская ракетка «перепрыгивает» назад со 108 до 102px ...

Как справиться с задержкой в ​​сети?Два дополнительных способа:

  • ждут подтверждения сервера перед выполнением действия
  • прогнозируют результаты действий (на стороне клиента и сервера)

Первый подход используется, когда влияние на клиента вряд ли связано с результатом и не может быть «откатом».Пример: когда клиент выпускает ракету, нельзя допустить, чтобы эта ракета подавлялась сервером при следующем обновлении, потому что у клиента фактически не было запаса ракет.Таким образом, в этом случае клиентское приложение запустит ракету только после того, как сервер отправил подтверждение.

Второй всегда используется, чтобы избежать этих «скачков» при синхронизации сервера.Вы должны контролировать сетевую задержку, чтобы предсказать движение ваших игровых элементов.Здесь два способа: вычислить пинг или синхронизировать время сервера и клиента при запуске (самый простой и надежный способ).Общая идея такова:

  • клиент отправляет сообщение "Я хочу переместить свою ракетку вниз во время = 1265871" и начинает двигаться

30 мс позже:

  • клиентская ракетка при y = 100 + 30 * 0.1 = 103px
  • сервер получает ход и вычисляет задержку в 30 мс (по разнице между пингом или синхронизацией по времени) и устанавливает положение ракетки при y = 100 + задержка * 0,1= 100 + 30 * 0,1 = 103px

Отлично!Они синхронизируются.

20 мс позже:

  • сервер и клиентская ракетка и при y = 103 + 20 * 0.1 = 105px
  • сервер отправляет новую позицию И направление

30 мс позже:

  • клиентская ракетка при y = 105 + 30 * 0.1 = 108px
  • клиент получает новую позицию И направление (105px при движении вниз),вычисляет задержку 30 мс и устанавливает позицию ракетки при y = 105 + задержка * 0,1 = 105 * 30 * 0,1 = 108px

Опять же, клиент и сервер синхронизируются!

Desync можетпроисходит на другом клиенте, когда первый клиент перестает двигаться.В этом случае ракетка игрока немного «прыгнет».Когда это не критично, можно сгладить этот переход.

Надеюсь, это поможет.

...