Допустим, у вас задержка 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 можетпроисходит на другом клиенте, когда первый клиент перестает двигаться.В этом случае ракетка игрока немного «прыгнет».Когда это не критично, можно сгладить этот переход.
Надеюсь, это поможет.