0

所以我正在用 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我究竟做错了什么?

4

2 回答 2

1

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

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

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

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

于 2012-08-28T05:59:44.017 回答
0

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

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

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

演示

于 2012-08-28T05:41:31.217 回答