在 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).
});
我正在使用 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).
});