Question

J'essaie de créer un jeu multijoueur en utilisant des websockets, des nœuds et du JavaScript. Quelle est la meilleure approche pour mettre à jour le client et garder une trace des coordonnées des clients sur le serveur. Ma méthode actuelle fonctionne, mais elle est très inefficace. (J'entends le ventilateur de mon ordinateur portable tourner un peu lol!).

Alors que se passe-t-il:

Le serveur attend que le client envoie un message 'startmove', qui contient également la direction. Une fois que le serveur a reçu ce message, il commencera à déplacer le lecteur et à diffuser sa position. Si le serveur a reçu le message 'stopmoving', qui contient également une direction ... il arrête de se déplacer dans cette direction.

Ma question:

Y a-t-il des ajustements que je peux utiliser pour augmenter les performances?

Extrait de code du serveur

var player =  {     x: 100, 
                    y: 200,
                 left: false,
                right: false,
                 down: false,
                   up: false
              }
var count = 0;

io.sockets.on('connection', function(client){
    ++count;
    io.sockets.emit('player_count', count);
    io.sockets.emit('connect', { "x" : player.x, "y" : player.y });

    client.on('disconnect', function () {  
      --count;
      io.sockets.emit('player_count', count);
    });


    client.on('startmove', function(d){   
      var direction = d.d;
      if (direction == 0) //Left
      {
        player.left = true;  
      } 
      else if (direction == 1) //Up
      {
        player.up = true;
      } 
      else if (direction == 2) //Right
      {
        player.right = true;     
      } 
      else if (direction == 3) //Down
      {
        player.down = true;       
      }
    });    

    client.on('stopmove', function(d){      
      var direction = d.d;
      if (direction == 0) //Left
      {
        player.left = false;  
      } 
      else if (direction == 1) //Up
      {
        player.up = false;
      } 
      else if (direction == 2) //Right
      {
        player.right = false;    
      } 
      else if (direction == 3) //Down
      {
        player.down = false;       
      }      
    });

    setInterval(loop, 15); // 33 milliseconds = ~ 30 frames per sec

    function loop() {
      if(player.left)
      {
        player.x--;
        io.sockets.emit('position', {"x" : player.x, "y" : player.y });                
      } 
      else if (player.right)
      {
        player.x++;
        io.sockets.emit('position', {"x" : player.x, "y" : player.y });                
      }

      if(player.up)
      {
        player.y--;
        io.sockets.emit('position', {"x" : player.x, "y" : player.y });                
      } 
      else if (player.down)
      {      
        player.y++;
        io.sockets.emit('position', {"x" : player.x, "y" : player.y });        
      }                  
    }    
});

Extrait de code client

$(document).ready(function(){
  var canvas = document.getElementById('game'),
      ctx    = canvas.getContext('2d'),
      socket = io.connect('http://localhost'); 

  //Only start the game upon receiving the connect message
  socket.on('connect', function(data){      
    var y = data.y;
    var x = data.x;

        //Constants
    var GAME_WIDTH = $('canvas').width(),
        GAME_HEIGHT = $('canvas').height();

    var Player = function(x,y,w,h){
      this.x = x;
      this.y = y;
      this.w = w;
      this.h = h;
    };  

    var Game = new function(){

      var player   = new Player(x, y, 100, 100),   
          left     = false,
          right    = false,
          up       = false,
          down     = false;

      /* Gather player input */      
      $(document).keydown(function(event) 
      {
        if ( event.keyCode == 37) //Left
        { 
          socket.emit('startmove', {"d" : 0});
          return false;
        } 
        else if (event.keyCode == 38) //Up
        { 
          socket.emit('startmove', {"d" : 1});
          return false;
        } 
        else if (event.keyCode == 39) //Right
        {
          socket.emit('startmove', {"d" : 2});
          return false;
        } 
        else if (event.keyCode == 40) //Down
        {
          socket.emit('startmove', {"d" : 3});
          return false;
        }   
      });

      $(document).keyup(function(event)
      {
        if ( event.keyCode == 37)  //Left
        { 
          socket.emit('stopmove', {"d" : 0});
          return false;
        } 
        else if (event.keyCode == 38) //Up
        {
          socket.emit('stopmove', {"d" : 1});
          return false;
        } 
        else if (event.keyCode == 39) //Right
        {
          socket.emit('stopmove', {"d" : 2});
          return false;
        } 
        else if (event.keyCode == 40) //Down
        {
          socket.emit('stopmove', {"d" : 3});
          return false;
        }
      });

      socket.on('position', function(data){
        console.log("x: " + data.x + "\ny: " + data.y);
        player.x = data.x;
        player.y = data.y;
        clear();
        draw();
      });

      /* Clear the canvas */
      function clear(){
        ctx.clearRect(0,0,GAME_WIDTH, GAME_HEIGHT);
      }

      /* Draw to the canvas */
      function draw(){
        ctx.fillRect(player.x, player.y, player.w, player.h);
      }
    }();
  });
});

Dans le navigateur:

À l'écran

http://i.imgur.com/dkfSQ.png

Était-ce utile?

La solution

Utilisez des horodatages pour suivre depuis combien de temps un joueur se déplace sur le serveur.

Voici comment je procéderais côté serveur:

var player =  {     x: 100, 
                    y: 200,
            direction: -1,
         moving_since: 0
              }
var count = 0;

io.sockets.on('connection', function(client){
    ++count;
    io.sockets.emit('player_count', count);
    io.sockets.emit('connect', { "x" : player.x, "y" : player.y });

    client.on('disconnect', function () {  
      --count;
      io.sockets.emit('player_count', count);
    });


    client.on('startmove', function(d){
      player.direction = d.d;
      player.moving_since = Date.now();   
    });    

    function adjustCoord(){
      player.direction = -1;
      var now = Date.now();
      if( player.direction == 0){
          player.x = player.x - ((now - player.moving_since) / 33);
      }
      else if( player.direction == 1){
          player.y = player.y + ((now - player.moving_since) / 33);
      }
      else if( player.direction == 2){
          player.x = player.x + ((now - player.moving_since) / 33);
      }
      else if( player.direction == 3){
          player.y = player.y - ((now - player.moving_since) / 33);
      }
    }

    client.on('stopmove', adjustCoord);

    setInterval(loop, 15); // 33 milliseconds = ~ 30 frames per sec

    function loop() {
      if ( player.direction != -1){
          var prevDir = player.direction;
          adjustCoord();
          player.direction = prevDir;
      }

      io.sockets.emit('position', {"x" : player.x, "y" : player.y });
    }    
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top