同时摆脱数组中的两个元素

时间:2012-08-28 05:37:41

标签: javascript arrays multidimensional-array

所以我正在用JavaScript设计一款游戏,而且我在解决与碰撞检测功能有关的问题时遇到了一些麻烦。 它是小行星,因此一些对象被相应命名。

我的碰撞检测功能用于检查玩家与小行星,子弹和小行星之间是否存在碰撞。在子弹和小行星的情况下,人们会期望子弹和小行星都消失。

然而,考虑到我是如何检查碰撞,移除子弹和小行星它碰撞似乎是一个挑战。这是我的相关代码:

for (var i=0;i<$_.mapObjs.length;i++) { //get one object to check
    var superBox = $_.mapObjs[i].hitBox; //get it's properties
    var objectName = $_.mapObjs[i].name;
    var isAsteroid =(objectName.indexOf("asteroid") == -1)?false:true; //is the object an asteroid?
    for (var y=0;y<$_.mapObjs.length;y++) { //get the object to check it against
        if (objectName !== $_.mapObjs[y].name) { //if we are not checking the object against its self
            var subName = $_.mapObjs[y].name;
            var subIsAsteroid = (subName.indexOf("asteroid") == -1)?false:true; //is the second object an asteroid?
            if (!(isAsteroid) || !(subIsAsteroid)) { //if we are not checking two asteroids against each other
                var subBox = $_.mapObjs[y].hitBox;
                var collision = rectIntersectsRect(superBox,subBox); //check for a collision using rectIntersectsRect
                if (collision) { //if there is a collision
                    if ((objectName == "player" && subIsAsteroid) || (isAsteroid && subName == "player")) { //if either of the objects are the player, then the player dies
                        if (!player.invincible)
                            player.death(); 
                    } else if ((objectName == "blankObject" && subIsAsteroid) || (isAsteroid && subName == "blankObject")) { //if either of the objects are a bullet, then we destroy the asteroid
                        Console.log(i + "," + y); //this is the problem area
                        Console.log("getting rid of " + objects[i].name + " and " + objects[y].name);
                        if (subIsAsteroid) { //splice the asteroid out of the second array
                            objects.splice(y,1);
                        } else { //splice the asteroid out of the first array
                            objects.splice(i,1);
                        }
                    }
                }
            }
        }
    }
}

现在,因为我需要小行星和子弹在碰撞时消失,我改变了

if (subIsAsteroid) {
    objects.splice(y,1);
} else {
    objects.splice(i,1);
}

objects.splice(y,1);
objects.splice(i,1);

然后,每当发生碰撞时,该函数会随机删除数组中的两个对象,即使yi的位置都指向子弹和小行星对象。我究竟做错了什么?

2 个答案:

答案 0 :(得分:1)

.splice()不只是删除随机元素,但在.splice(y,1)操作删除一个元素后,y之后所有元素的索引将比以前少一个 - 所有这些后来的元素“向上移动”。因此,如果i大于y,则它将不再引用您想要的元素。

如果您首先删除具有较高索引的元素,则应该没问题:

objects.splice(Math.max(y,i), 1);
objects.splice(Math.min(y,i), 1);

话虽如此,我无法从您的代码中看出$_.mapObjsobjects之间的关系是什么,但我认为这可能会导致问题。您使用$_.mapObjsy作为循环索引迭代i的嵌套循环,然后根据objects和{{1}从y中删除元素来自i的索引。这两个数组是否具有相同顺序的相同元素? 这可以解释您的“随机”元素删除。您应该拼接出$_.mapObjs吗?如果是这样,您需要在删除后调整$_.mapObjsy,以便在下一次循环迭代时不跳过元素。

答案 1 :(得分:0)

这可能是因为当您拼接第一个索引时,您的数组会发生变化。这意味着第二个索引可能正确也可能不正确;因为元素的索引已经改变了。我建议你做这样的事情:

objects[y] = null;
objects[i] = null;

while( (remIndex = objects.indexOf(null)) !== -1 ){
    objects.splice(remIndex, 1);
}

Demo