在 socket.io 多人棋盘游戏中避免多次移动

Avoid multiple moves on socket.io multiplayer board game

我正在使用 socket.io 创建一款回合制多人棋盘游戏。如果客户端在板上移动,我想再次禁用移动,但我不知道如何实现。

当客户端移动时,它会将棋盘状态发送给服务器,然后服务器将棋盘状态发送给每个连接的客户端。甚至是主动的人。

这是我从客户端向服务器发送棋盘状态的方式:

sock.emit("message", board, turn); // Sending the board state to the server
canvas.removeEventListener("click", game);

这是服务器获取更新的板状态并将其发送给每个客户端的方式:

  // If we recieve the board state from a client
  sock.on("message", (board, turn) => {
    io.emit("message", board, turn); // Sending the board state to every client who is connected
  });

这是客户端代码在从服务器获取新的棋盘状态时的处理方式:

sock.on("message", (board, turn) => {
  this.board = board;
  this.turn = turn;
  render(board);

  canvas.addEventListener("click", game);

  setTimeout(function () {
    if (winningMove(board)) {
      // disable click event on both client
      // tell the server that the game ended
      sock.emit("end");
      sock.on("end", () => {
        window.alert("Game Over...");
        window.location.reload();
      });
    }
  }, 100);
});

您可以使用 socket.id 值来唯一标识每个连接的客户端(在您的情况下为 player/board)并在服务器端添加逻辑以防止来自同一客户端的多次移动。

选项 1

跟踪最后一次移动的客户并忽略来自同一客户的任何新移动。 实现看起来像这样:

  // Variable to track last played client
  let lastPlayedClient = null;

  // If we recieve the board state from a client
  sock.on("message", (board, turn) => {
    // Ensure move is made by different client
    if (lastPlayedClient !== sock.id) {
      // Update last played client to current client id
      lastPlayedClient = sock.id;
      io.emit("message", board, turn); // Sending the board state to every client who is connected
    }
  });
 

选项 2

在服务器端,添加逻辑来识别必须进行下一步操作的客户端。然后只允许该客户进行下一步操作。忽略任何其他客户所做的动作。 实现看起来像这样:

  // Variable to track client id of next player
  let nextPlayer = yourLogicToIdentifyNextPlayer();

  // If we recieve the board state from a client
  sock.on("message", (board, turn) => {
    // Ensure move is made by the identified client only
    if (nextPlayer === sock.id) {
      io.emit("message", board, turn); // Sending the board state to every client who is connected
    }
  });

为了提高用户体验,您可以在第一步操作后立即禁用前端板上的输入。

参考:Socket#id

如果我对你的问题的理解正确,你想向所有客户端发送 move 信号,但向右发出请求(移动)的客户端除外?

然后使用 socket.broadcast.emit

  // If we recieve the board state from a client
  sock.on("message", (board, turn) => {
    // io.emit("message", board, turn); // Sending the board state to every client who is connected
    socket.broadcast.emit("message", board, turn) // sends to every client except the client who made this request (socket.id).
  });