gpt4 book ai didi

javascript - 拼接后Javascript覆盖数组索引

转载 作者:行者123 更新时间:2023-11-30 20:27:31 25 4
gpt4 key购买 nike

我遇到了一个问题,似乎我在拼接后覆盖了数组索引,至少我认为是这样。它适用于使用 Phaser 2 构建的小游戏。它本质上只是一个小型多人跳跃游戏,可以获得一些客户端/服务器架构的经验。正在使用 socket.io 和 express。我的问题似乎出在服务器上,当客户端断开连接时,当它从玩家列表中删除时,仍在游戏中的其他玩家似乎覆盖了断开连接的玩家的索引。为了调试这个,我主要使用控制台日志,使用 for 循环遍历列表并打印出玩家的套接字 ID。因此,例如,如果我使用插槽 ID 1 的玩家 1 加入,然后使用插槽 ID 2 的玩家 2 加入,然后玩家 2 离开,for 循环将打印出 1、1。如果使用插槽 ID 3 的新玩家 3 在玩家之后加入2 已经离开,打印出玩家的 ID 将打印出 1、1、3。起初我认为问题是在 onNewPlayer(data) 函数中,我遇到了别名问题,因为我在两个中使用了 var currentInfo不同的地方,所以我将第二个对象更改为 var info。这似乎是某种别名问题,还是我应该在其他地方搜索此问题?如果需要,我可以提供额外的代码,到目前为止,我们所有关于玩家创建和移动的回调都运行良好。谢谢。

下面是相关的服务端代码

var players[];
//When a new player is made, save it
function onNewPlayer(data) {
var newPlayer = new Player(data.x, data.y, this.id);

var currentInfo = {
x: newPlayer.x,
y: newPlayer.y,
id: newPlayer.id,
};

for(i = 0; i < players.length; i++) {
//broadcast the new player out to all the other players in the list
this.broadcast.emit("newEnemy", currentInfo);
}

//check for if there are already players,
//if so, send the player's who are already in the game to the new player
if(players.length > 0) {
for(i = 0; i < players.length; i++) {
var info = {
x: players[i].x,
y: players[i].y,
id: players[i].id,
};
this.emit("newEnemy", info);
}
}

players.push(newPlayer);
for(i = 0; i < players.length; i++) {
console.log(players[i].id);
}
}

function onDisconnect(){
console.log("User " + this.id + " disconnected");
//find the user in the list of players and remove them, then tell the client
for(i = 0; i < players.length; i++) {
if(players[i].id === this.id) {
console.log("removing this player " + this.id);
//TODO trying a different broadcast
this.broadcast.emit("playerDisconnect", this.id);
console.log(players[i].id);
players.splice(i, 1);
}
}
}

下面是相关的客户端代码

//We've lost connection with the server!
function onSocketDisconnect() {
console.log("Lost connection with server!");
};

//When the server notifies the client an enemy has disconnected,
//search for it in the enemies list and stop rendering it
function onEnemyDisconnect(data) {
//TODO
for(i = 0; i < enemies.length; i++) {
if(enemies[i].id == data) {
//TODO
console.log("destroying");
enemies[i].destroy();
enemies.splice(i, 1);
}
}
}

最佳答案

您正在使用 for 循环在正向迭代一个数组,并使用 .splice() 从数组中删除元素。这将无法正常工作,因为当您调用 .splice() 从数组中删除一个项目时,它会将数组中后面的元素复制到一个位置。但是,您的 for 循环索引指向数组中的下一个元素。最终结果是您跳过了数组中的迭代项。

有多种可能的解决方案。

  1. 您可以向后而不是向前迭代数组。当以相反的顺序迭代时,您尚未迭代的元素不受您的 .splice() 的影响,并且它工作得很好。

  2. 您可以在 for 循环中停止修改数组。也许您收集了一组要删除的索引,然后从后向前删除它们。

  3. 您可以使用 .filter() 创建一个新数组,该数组是原始数组的一个子集,并且在完成 .filter() 操作后只需将新数组分配给您的变量并从那时起使用它。

  4. 您可以按原样保持迭代,但在调用 .splice() 后通过将 for 循环索引减一来更正它。

这是反向数组迭代的示例:

// When the server notifies the client an enemy has disconnected,
// search for it in the enemies list and stop rendering it
function onEnemyDisconnect(data) {
// use reverse iteration to avoid skipping elements when calling .splice()
for (i = enemies.length - 1; i >= 0; i--)
if(enemies[i].id == data) {
console.log("destroying");
enemies[i].destroy();
enemies.splice(i, 1);
}
}
}

这是一个 .filter() 示例,假设您可以分配给 enemies 并且新数组将永久取代它:

// When the server notifies the client an enemy has disconnected,
// search for it in the enemies list and stop rendering it
function onEnemyDisconnect(data) {
enemies = enemies.filter(item => {
if (item.id === data) {
console.log("destroying");
item.destroy();
return false; // don't keep this one
}
return true;
});
}

关于javascript - 拼接后Javascript覆盖数组索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50730643/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com