简体   繁体   English

同时去除数组中的两个元素

[英]Getting rid of two elements in an array at the same time

So I'm designing a game in JavaScript, and I'm having some trouble with the way things are removed relating to my collision detection function. 因此,我正在使用JavaScript设计游戏,并且在与碰撞检测功能有关的移除方式方面遇到了一些麻烦。 It's Asteroids, so some of the objects are named accordingly. 它是小行星,因此其中一些对象是相应命名的。

My collision detection function is designed to check if there are collisions between the player and an asteroid, or a bullet and an asteroid. 我的碰撞检测功能旨在检查玩家与小行星或子弹与小行星之间是否存在碰撞。 In the case of a bullet and an asteroid, one would expect both the bullet and the asteroid to disappear. 对于子弹和小行星,人们会希望子弹和小行星都消失。

However, given how I'm checking for collisions, removing both the bullet and the asteroid it's collided with seems to be a challenge. 但是,考虑到我要检查碰撞的方式,将子弹和与之相撞的小行星都移除似乎是一个挑战。 Here is my relevant code: 这是我的相关代码:

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);
                        }
                    }
                }
            }
        }
    }
}

Now, because I need both the asteroid and bullet to dissapear when they collide, I change 现在,因为小行星和子弹碰撞时都需要消失,所以我改变了

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

to

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

but then, whenever there is a collision, the function randomly deletes two objects off the array, even though the positions of both y and i refer to the bullet and asteroid objects. 但是,每当发生碰撞时,即使yi的位置都引用了子弹和小行星对象,该函数也会从数组中随机删除两个对象。 What am i doing wrong? 我究竟做错了什么?

.splice() doesn't just remove random elements, but after the .splice(y,1) operation removes one element the indexes of all the elements after y will be one less than before - all of these later elements "move up". .splice()不仅会删除随机元素,而且在.splice(y,1)操作删除一个元素之后, y之后所有元素的索引将比以前少一个-所有这些后面的元素都会“向上移动” 。 So if i is greater than y it will no longer refer to the element you want it to. 因此,如果i大于y ,它将不再引用您想要的元素。

If you remove whichever element has a higher index first it should be fine: 如果先删除索引较高的元素,那应该没问题:

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

Having said that, I can't tell from your code what the relationship between $_.mapObjs and objects is but I think it might cause problems. 话虽如此,我无法从您的代码中看出$_.mapObjsobjects之间的关系是什么,但我认为这可能会引起问题。 You have nested loops iterating over $_.mapObjs with y and i as loop indexes, but then you remove elements from objects based on the y and i indexes from $_.mapObjs . 您有嵌套循环,使用yi作为循环索引遍历$_.mapObjs ,但是随后您从$_.mapObjs基于yi索引的objects删除了元素。 Do these two arrays have the same elements in the same order? 这两个数组的元素顺序相同吗? This could explain your "random" element removal. 这可以解释您删除“随机”元素的原因。 Should you be splicing out of $_.mapObjs ? 您应该拼接出$_.mapObjs吗? If so, you'd need to adjust y and i after the removal so that you don't skip elements on the next loop iteration. 如果是这样,则在删除后需要调整yi ,以免在下一次循环迭代时跳过元素。

This is probably because when you splice the first index, your array changes. 这可能是因为在拼接第一个索引时,数组会发生变化。 This means that the second index may or may not be correct; 这意味着第二个索引可能正确也可能不正确; because the indices of the elements have changed. 因为元素的索引已更改。 I'd recommend you to do something like this: 我建议您做这样的事情:

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

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

Demo 演示版

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM