2016-03-21 1 views
4

Я только что сделал многопользовательскую реализацию браузера игры Pong, используя socket.io, и у вас возник вопрос о логистике реального времени. В основном игровой манипулятор - это только цветной div, который перемещается вверх или вниз в зависимости от того, какую кнопку они нажимают. Я заметил, что при тестировании моей программы на двух разных компьютерах с использованием AWS было почти идеально синхронизировано, но иногда не точное. Для игрока, который управляет веслом, перемещение их весла выполняется локально, но для человека, которого он играет против сервера, постоянно отправляет им данные о том, движется ли их противник вверх или вниз.Позиция игрока на стороне сервера или на стороне клиента?

Вопрос в том, должен ли я делать все движения на стороне сервера? Как пользователь нажимает, чтобы подняться, и он отправляет серверу запрос, который испускает обоих игроков, что весло должно двигаться, или мой способ, когда движение для вашего весла выполняется локально нормально?

Мой код прямо сейчас выглядит следующим образом:

проверки на стороне клиента, если вверх или вниз кнопки нажимается и испуская запрос перемещения:

paddleMove = 0; // Keep track of which direction to move 
speed = 5; 
    if (paddleL.position().top > arena.position().top){ // If left paddle not at top 
     if (keysPressed.up) paddleMove -= speed; 
    } 
    if (paddleL.position().top+paddleL.height() < arena.position().top + arena.height() - 15){ // If left paddle not at bottom 
     if (keysPressed.down) paddleMove += speed; 
    } 
    paddleL.css({ // Move paddle locally 
     top: paddleL.cssNumber('top') + paddleMove + 'px' 
    }); 
    socket.emit("moveReq", paddleMove); // Send to server 

Вышеприведенный код находится в интервале, который проходит каждую фракцию Второй.

Затем на стороне сервера выглядит следующим образом:

socket.on('moveReq', function(data){ // Send to opponent that other paddle moved 
    socket.broadcast.emit("movePaddle", data); 
}); 

Что в предупреждениях своей очереди другая часть пользовательского кода на стороне, чтобы переместить другую ракетку:

socket.on("movePaddle", function(data){ 

     var paddleMove = 0; 
     paddleMove += data; // Data is speed (direction) of movement 
     paddleR.css({ // Move right paddle 
      top: paddleR.cssNumber('top') + paddleMove + 'px' 
     }); 

Как я уже говорил, движение сейчас довольно хорошо, но не идеально. Должен ли я сделать ни одно из локальных движений и не сделать все это на сервере?

+0

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

ответ

2

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

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

4

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

До сих пор, что мы делали, было прогнозирование и lerping. Предположим, что есть два игрока, подключенные по имени A & B.

Скажем, игрок A по умолчанию находится на x = 0 (t = 0), поэтому на B он также будет на x = 0. Теперь то, что мы будем делать это будет начать непосредственно излучающих A X-positon раз в 1 сек (в зависимости от вашей игры, если кадр затем уменьшите значение)

После 1 сек (т = 1), позиция A находится на x = 2 (2px в соответствии с вами). B получает позицию A после 1.2 секунд (учитывая поздние из-за проблем с сетью). Теперь нам нужно поднять положение от x = 0 до x = 1, прогнозируя время.(Все это может быть достигнуто с помощью сценариев)

Базовая формула (Это будет сделано в функции обновления) :

CurrentXposition = (NewXPosition - CurrentXPosition) * deltatime ; 

Ну вы должны обязательно работать на указанной выше формуле. Дельтатимы будут вычисляться каждый раз, когда мы получим новую позицию. Итак, здесь мы задерживаем и прогнозируем все в одном, используя deltatime.

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

Refer this blog for more into this ,

And This for lerping formula

+0

спасибо за это. Однако у меня проблемы. Я отправляю «NewXPosition» каждые 250 мс или около того, но при интерполяции символ «перескакивает», если хотите, всякий раз, когда обновляется «NewXPosition». Должен ли я посылать новое значение lerping той же скорости, что и игры fps? –

+1

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