根据对象值从数组中删除对象

时间:2014-12-22 16:12:49

标签: javascript arrays canvas

我的JavaScript游戏遇到了一些问题。我在屏幕上有3个敌人,他们可以被可控制的玩家击中。问题是,当你杀死某些敌人时,它们会被移除,但有时也会被移除。

以下代码用于输入这些变量(x,y和角度可能不同):

enemys - 一系列对象:

{
  x: 646,
  y: 343,
  angle: 137,
  speed: 0,
  canSeePlayer: 0,
  health: 10,
  fireCooldown: 10
}

代码:

enemys.forEach(function(enemy) {
    var enemyIndex = enemys.indexOf(enemy);
    if (enemys[enemyIndex].health <= 0) {
        enemys.splice(enemy, 1);
    }
});

是否可以更容易地根据值从数组中删除对象?

1 个答案:

答案 0 :(得分:1)

从文档中,array.splice()需要一个索引,而不是一个对象:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

所以你可以使用:

enemys.splice(enemyIndex, 1);

然而,有更好的方法......试试这个:

function IsDead( enemy ) {
    if( enemy.health <= 0 ) {
        return true;
    } else {
        return false;
    }
}

function RemoveDead( enemys ) {
    var deadEnemies = enemys.find( IsDead );
    for( enemy in deadEnemies ) {
        enemys.slice( enemys.indexOf( enemy ), 1 );
    }
}

现在只需运行代码:

RemoveDead( enemys );

这是新的&#34; array.find()&#34;功能文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

现在为什么要这样做的一些原因:

  1. 它可以重复使用! - 两个功能,随时随地都易于使用。
  2. 它的可读性! - 乍一看,我们不知道enemys.forEach(....)做了什么。 RemoveDead()非常简单,只需要不到一秒的时间就能知道你在做什么。
  3. 很干净! - 也许是多余的,但是当你编写1000行代码时,这是一个很长的路!
  4. &#34;这有更多代码&#34; - 是的,它确实。但是看看代码是如何可重用的。 &#34; IsDead()&#34;可以随时调用任何敌人物体。它非常方便! (你可能已经有了一个)

    我强烈建议将这些函数命名为与敌人使用的对象类相关。如果敌人对象类的类型是:&#34; Sprite&#34;或者&#34; Enemy&#34;然后使用&#34; IsSpriteDead&#34;或者&#34; IsEnemyDead&#34;和#34; RemoveDeadSprites&#34;或者&#34; RemoveDeadEnemies&#34; (注意敌人的复数是敌人)。我们之所以要这么做,是因为如果你有一个Enemy类型的对象和一个Friend类型的对象,但他们都没有&#34;健康&#34;变量,您可能会不小心使用RemoveDead()数组作为参数调用Friends - 这不会起作用,您可能无法理解错误。但如果该函数巧妙地命名为RemoveDeadEnemies(),您将记住这只适用于Enemy类型对象。我知道这是基本的,但它确实有帮助! :)

    最后一件事......如果您构建一个新的数组对象并将RemoveDead( enemys );更改为enemys.removeDead()

    ,您可以做得更好

    深思熟虑。 :)

    编辑:

    MarkE指出了一个更好的方法来做到这一点值得赞扬:

    让我们为isDead()对象添加Enemy方法(假设如上)。

    {
      x: 646,
      y: 343,
      angle: 137,
      speed: 0,
      canSeePlayer: 0,
      health: 10,
      fireCooldown: 10,
      isDead: function() {
        return this.health<=0;
      }
    }
    

    现在我们删除上面的IsDead()函数并修改我提到的RemoveDead()函数:

    function RemoveDead( enemys ) {
        var deadEnemies = enemys.find( function(enemy){ return enemy.isDead(); } );
        for( enemy in deadEnemies ) {
            enemys.slice( enemys.indexOf( enemy ), 1 );
        }
    }
    

    现在注意Enemy对象本身确定它是否已经死亡。如果还有另一个我们想要考虑的因素,那么MarkE的巨大道具就是这样吗?也许以后Enemy可以拥有一个无敌的&#34;属性。您必须找到并修改所有死亡代码。但是如果使用Enemy对象的属性,我们可以简单地将代码更改为:

    isDead: function() {
        return (this.health<=0 && !this.invincible);
    }
    

    这就是它的全部内容。 MarkE还指出使用isDead()属性,您可以轻松地忽略死敌并在以后重复使用它们。

    谢谢MarkE! :)