Подтвердить что ты не робот

Многопользовательская игра для JavaScript, построенная с помощью Node.JS - Разделители

У меня есть вопрос, на который я не могу найти ответ.

Я экспериментирую с созданием многопользовательской игры с Node.JS и Socket.IO. Я создал чат в качестве своего первого эксперимента, поэтому у меня есть трансляции, работающие и т.д. Теперь я нахожусь в точке, где хочу получить что-то, работающее с Canvas.

Проблема, с которой я столкнулась, - это получить голову от нескольких независимых игроков. Я знаю, что каждый игрок отправит свои x, y корды на сервер, и сервер будет транслировать их, но как клиент знает, сколько игроков будет отображаться, я предполагаю, что их нужно хранить в массиве где-то.

4b9b3361

Ответ 1

Моя реализация будет очень наивной и упрощенной, без компенсации отставания, экстраполяции и т.д., но она должна указывать на общую концепцию "многопользовательской" работы с node.

Я думаю, что самый простой подход - иметь ассоциативный массив, содержащий игроков (сущностей) как на клиенте, так и на сервере. Затем с клиентской стороны вы отправляете команды типа {action: "move", target:[32, 100]} и обрабатываете эту команду с помощью логики сервера (где работает настоящая игра). Каждому сокету on connection следует назначить объект или идентификатор игрока, чтобы вы могли получить к нему доступ, например:

var lastPlayerID = 0;
var players = {};

server.on("connection", function(socket) {

  var newcommer = new Player({id: lastPlayerID});      
  players[lastPlayerID] = newcommer;
  socket.player = newcommer; // or lastPlayerID
  lastPlayerID++;      

  socket.onMessage = function(message) {
    this.player.doSomething(); 
  }

});

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

{
  timestamp: game.delta,
  players: {
    1: {x: 32, y: 100},
    2: {x: 14, y: 11}
  }
}

И затем на стороне клиента получают данные и интерполируют от старых к новым значениям.

// duration in this simplified example is snapshot sending interval in [ms]
Player.prototype.interpolateTo = function(data, duration) {
  if(typeof data.x != "undefined") {
    // step needed to get `destination x` within `duration` miliseconds
    this.stepValues.x = Math.abs(data.x - this.x) / duration;
    this.target.x = data.x;
  } 
  // ...
}

// step you call for each game loop iteration
Player.prototype.step = function(delta) {
  if(this.x < this.target.x) {
    this.x += delta * this.stepValues.x
  }
}

Это достаточный алгоритм для игры в полу-аркаду с максимум 20 объектами. Уменьшение интервала моментального снимка делает его почти подходящим для стратегической игры с большим количеством объектов. Ваш главный враг - использование полосы пропускания, которое можно уменьшить, минимизируя размер пакета. Например, прочитайте о BiSON, LZW и не отправляйте данные, которые не изменились с момента последнего моментального снимка.

Моя репутация не позволяет мне публиковать все ссылки, поэтому я добавил их сюда: http://pastebin.com/Kh3wvF1D

Общее введение в многопользовательские концепции Гленна Фидлера:

http://gafferongames.com/networking-for-game-programmers/what-every-programmer-needs-to-know-about-game-networking/

Некоторые многопользовательские методы от Quake: Это даст вам подсказку об интерполяции и экстраполяции (предсказании)

http://fabiensanglard.net/quakeSource/quakeSourcePrediction.php

Статья клапана о компенсации задержек и общих оптимизациях:

https://developer.valvesoftware.com/wiki/Latency_Compensating_Methods_in_Client/Server_In-game_Protocol_Design_and_Optimization

Многопользовательские методы в Age of Empires:

http://zoo.cs.yale.edu/classes/cs538/readings/papers/terrano_1500arch.pdf#search=%22Real%20time%20strategy%20networking%20lockstep%22

Вы также можете прочитать мою статью об оптимизации использования полосы пропускания

http://rezoner.net/minimizing-bandwidth-usage-in-html5-games-using-websocket,299

+1 для Ivo Wetzel Mapple.js это большая куча знаний.

https://github.com/BonsaiDen/Maple.js

Ответ 2

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

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

Затем каждый клиент принимает все эти дельты игроков и отображает их. Что касается реализации на стороне клиента, у меня будет какой-то объект Board/Map, и у него будет список RenderableEntities. Затем я просто обновляю RenderableEntities с новыми позициями и периодически перерисовываю все объекты.

Я рекомендую вам взглянуть на Maple.js

Ответ 3

Другим способом синхронизации координат X и Y каждого игрока является использование Lance. Это библиотека JavaScript с открытым исходным кодом, которая обрабатывает коррекцию положения для нескольких игроков с авторитетным сервером.

Это будет полезно, если вам нужно синхронизировать другие вещи, кроме координат, например, имя объекта или свойства аватара. Или, если у ваших игроков есть скорости.