2016-03-12 2 views
0

Я занимаюсь созданием многопользовательской игры в пространстве в реальном времени. Сначала я создал только однопользовательскую локальную версию игры, чтобы посмотреть, как это можно сделать. Игра проходила гладко со стабильным 60 fps. Я был доволен ядром и производительностью, поэтому начал переносить его для версии с несколькими проигрывателями. В качестве сервера для игры я использую node.js.node.js и canvas, gameloop вне синхронизации

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

Вопрос в том, какой метод следует использовать для игрового цикла на стороне сервера?

Сервер вычисляет положение врагов и пули врагов. Я использовал setInterval метод:

setInterval(function() { 
    for(var i = 0; i < enemies.length; i++) { 
     var enemy = enemies[i]; 
     enemy.move(); 
     enemy.fire(); 
    } 
    io.emit('enemies', enemies); 
}, 1000/60) 

функция противника двигаться, как это:

this.move = function() { 
     this.x += (this.movX - this.x)/this.speed; 
     this.y += (this.movY - this.y)/this.speed; 
    }; 

На стороне клиента я запустить requestAnimationFrame цикл:

socket.on('enemies', function(enemies) { 
    self.enemies = enemies; 
}); 
var run = function() { 
    for(var i = 0; i < self.enemies.length; i++) { 
     (function(i) { 
      var enemy = self.enemies[i]; 
      if(enemy.alive) { 

       for(var i = 0; i < enemy.primary_bullets_pool.length; i++) { 
        var bullet = enemy.primary_bullets_pool[i]; 
        if(bullet.alive) { 
         self.context.fillStyle = 'red'; 
         self.context.fillRect(bullet.x, bullet.y, bullet.w, bullet.h); 
        } 
       } 

       self.context.drawImage(self.images[enemy.model], enemy.x, enemy.y, enemy.w, enemy.h); 
      } 
     }(i)); 
    } 

    window.requestAnimationFrame(run); 
}; 

Теперь пользователь опыт очень плохо. Враги «прыгают» на экран вместо того, чтобы двигаться плавно. Я экспериментировал с временным интервалом. Если поставить 10 мс вместо 1000/60 - это будет немного лучше, но дрожь все еще видна. Каков правильный способ сделать так, чтобы каждый игрок мог видеть врагов в одной и той же позиции в любой момент времени, и движение выполняется плавно?

ответ

1

Как бы то ни было, похоже, что вы обновляете позиции противника на каждом «тике», который, как вы заметили, будет казаться нервным, если сервер не сможет достаточно быстро обновить свои позиции.

В идеале, вы не хотите, чтобы ваш сервер должен постоянно выделять события для всех врагов всем игрокам, чтобы добиться плавного движения. Это накладные расходы на то, что должно быть полностью обработано клиентом.

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

Некоторые ответы на this question из GameDev Stack Exchange должны указывать вам в правильном направлении для реализации функции «двигаться в направлении».