Анимация в JS имеет нежелательную небольшую задержку - PullRequest
0 голосов
/ 12 ноября 2019

Я делаю многопользовательскую игру на html5 с использованием socket.io и node.js, у меня есть два основных файла: app.js: сервер, Index.html: Client. У меня есть анимация ходьбы, для начала которой требуется некоторое время. Я попытался уменьшить и увеличить частоту кадров анимации в setInterval и даже отредактировать само изображение, но ничего не помогло.

Вот мой код:

index.html:

  id="ctx"
  width="1920"
  height="1080"
  style="border:1px solid #000000;"
></canvas>

<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
  var img = {};
  img.player = new Image();
  img.player.src = "/client/img/sprite_01_male.png";
  var sx = 0;
  var sy = 0;
  var ctx = document.getElementById("ctx").getContext("2d");
  ctx.font = "30px Arial";

  var socket = io();

  reset_sx = function() {
  if (sx > 96) {
    console.log(sx);
    sx = 0;
  }
}

  socket.on("newPositions", function(data) {
    ctx.clearRect(0, 0, 1920, 1080);
    for (var i = 0; i < data.length; i++)
      ctx.drawImage(img.player, sx, sy, 32, 48, data[i].x, data[i].y, 32, 48);

  });



  document.onkeydown = function(event) {
    if (event.keyCode === 68) {
      socket.emit("keyPress", { inputId: "right", state: true });
      sx += 32;
      sy = 96;
    }
    //d
    else if (event.keyCode === 83) {
      socket.emit("keyPress", { inputId: "down", state: true });
      sx += 32;
      sy = 0;
    }
    //s
    else if (event.keyCode === 65) {
      socket.emit("keyPress", { inputId: "left", state: true });
      sx += 32;
      sy = 48;
    }
    //a
    else if (event.keyCode === 87) {
      socket.emit("keyPress", { inputId: "up", state: true });
      sx += 32;
      sy = 144;
    }
    // w
    reset_sx();
  };
  document.onkeyup = function(event) {
    if (event.keyCode === 68) {
      socket.emit("keyPress", { inputId: "right", state: false });
      sx = 0;
    }
    //d
    else if (event.keyCode === 83) {
      socket.emit("keyPress", { inputId: "down", state: false });
      sx = 0;
    }
    //s
    else if (event.keyCode === 65) {
      socket.emit("keyPress", { inputId: "left", state: false });
      sx = 0;
    }
    //a
    else if (event.keyCode === 87) {
      socket.emit("keyPress", { inputId: "up", state: false });
      sx = 0;
    }
    // w
  };
</script>

app.js:

<canvas
  id="ctx"
  width="1920"
  height="1080"
  style="border:1px solid #000000;"
></canvas>

<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
  var img = {};
  img.player = new Image();
  img.player.src = "/client/img/sprite_01_male.png";
  var sx = 0;
  var sy = 0;
  var ctx = document.getElementById("ctx").getContext("2d");
  ctx.font = "30px Arial";

  var socket = io();

  reset_sx = function() {
  if (sx > 96) {
    console.log(sx);
    sx = 0;
  }
}

  socket.on("newPositions", function(data) {
    ctx.clearRect(0, 0, 1920, 1080);
    for (var i = 0; i < data.length; i++)
      ctx.drawImage(img.player, sx, sy, 32, 48, data[i].x, data[i].y, 32, 48);

  });



  document.onkeydown = function(event) {
    if (event.keyCode === 68) {
      socket.emit("keyPress", { inputId: "right", state: true });
      sx += 32;
      sy = 96;
    }
    //d
    else if (event.keyCode === 83) {
      socket.emit("keyPress", { inputId: "down", state: true });
      sx += 32;
      sy = 0;
    }
    //s
    else if (event.keyCode === 65) {
      socket.emit("keyPress", { inputId: "left", state: true });
      sx += 32;
      sy = 48;
    }
    //a
    else if (event.keyCode === 87) {
      socket.emit("keyPress", { inputId: "up", state: true });
      sx += 32;
      sy = 144;
    }
    // w
    reset_sx();
  };
  document.onkeyup = function(event) {
    if (event.keyCode === 68) {
      socket.emit("keyPress", { inputId: "right", state: false });
      sx = 0;
    }
    //d
    else if (event.keyCode === 83) {
      socket.emit("keyPress", { inputId: "down", state: false });
      sx = 0;
    }
    //s
    else if (event.keyCode === 65) {
      socket.emit("keyPress", { inputId: "left", state: false });
      sx = 0;
    }
    //a
    else if (event.keyCode === 87) {
      socket.emit("keyPress", { inputId: "up", state: false });
      sx = 0;
    }
    // w
  };
</script>

1 Ответ

1 голос
/ 12 ноября 2019

Причина, по которой обновление занимает много времени, в основном из-за socket.io. Несмотря на то, что WebSockets имеют быстрые соединения, они могут запаздывать. Поэтому клиенту, вероятно, требуется время, чтобы отправить данные на сервер, сервер для выполнения расчетов и отправить обратно клиенту.

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

То, с чем вы можете иметь дело, это простая задержка. Википедия содержит статью о задержке, а также способах ее устранения.

Удачи в создании игры. ☺

...