【问题标题】:how to remove multiple elements in array in libgdx如何在libgdx中删除数组中的多个元素
【发布时间】:2017-03-26 13:59:12
【问题描述】:

我正在使用 libgdx,我有一个由我创建的球类数组列表。我正在尝试一次删除具有相同颜色的球。由于删除元素后数组中元素的位置发生了变化,这会留下一些元素未被删除。 所以我正在使用快照数组 https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/SnapshotArray.html

根据文档,如果我们在 array.begin() 和 array.end() 方法之间编写循环,则数组大小和索引不会改变。 所以我声明了快照数组

SnapshotArray<Ball> balls;

而我的删除方法是

 private void removeVillianGroups(int color){
        Ball[] ball=balls.begin();
        for(int i=0;i<balls.size;i++){

            if(balls.get(i).getColor()==color){
                ball.removeValue(balls[i],true);

            }
        }
        balls.end();
    }

我在投射时遇到错误

 java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lcom.mygames.haloween.Entity.Ball;

在上面这一行

Ball[] ball=balls.begin();

所以在这里我创建了我的数组,基本上我将屏幕宽度分成六个相等的部分,有 6 列球

 private void createVillians() {

      for (int color=0;color<4;color++)//create 4 diffirent color balls in 4 rows
        for(int i=0;i<6;i++)//each row contan 6 same color balls
{
       balls.add(new Ball(viewport,new Vector2(i*viewport.getWorldWidth()/6,
               0-c*viewport.getWorldWidth()/6),color));

//Ball class just draw balls according their color between 0 to 3.
        }
    }

【问题讨论】:

  • @Am_I_Helpful 它返回一个T[](即Ball[])。 @OP:你确定你没有使用原始类型吗?我们可以有更多的代码吗?此外,“由于删除元素后数组中元素的位置发生了变化” - 为什么不使用像 ArrayList 这样的动态集合呢?
  • 如果您在 api 页面上看到示例,它使用 Object[] 作为原始类型,这让我认为这是历史实现,并且在之后的某个时间添加了“T[]”支持,在这种情况下,您可以如果它是针对此 api 的最新版本,则共享库版本?
  • 我已经尝试过数组列表和延迟删除数组,由于删除迭代器跳过下一个元素后移动,因为它的位置现在是删除数组。在快照数组中,我的类型是定义类 Ball,它只绘制一个球精灵。看我的目标只是同时删除多个具有相同颜色的数组,我认为不需要更多代码,但如果需要我会发布
  • 你能告诉我你的推特账号吗?我们可以做朋友吗?

标签: java arrays libgdx


【解决方案1】:

你不能只使用一个常规的 ArrayList 并向后迭代吗:

ArrayList<Ball> balls;

private void removeVillianGroups(int color){
  for(int i = balls.size() - 1; i >= 0; i--){
        if(balls.get(i).getColor()==color){
            balls.remove(i);
        }
    }
}

【讨论】:

    【解决方案2】:

    您的原始代码给出 CCE 的原因是,如果您未在其构造函数中传入类类型,libgdx Array/SnapshotArray 类将返回 Object[]。如果您一次删除多个项目,则 SnapshotArray 可能比 Array 或 ArrayList 更快。

    您似乎也将快照数组与临时数组混淆了。并且注意balls.size在迭代过程中是不稳定的,所以你应该缓存它。您的代码应如下所示:

    private void removeVillianGroups(int color){
        Ball[] ball=balls.begin();
        for(int i=0, n=balls.size; i<n; i++){
            if(ball[i].getColor()==color){
                balls.removeIndex(i);
            }
        }
        balls.end();
    }
    

    【讨论】:

    • 我关注了你,但我不知道为什么 CCE 仍然存在于你的代码的第二行。
    • 因为在 Java 中泛型只是语法糖。 Array 类实际上并不知道它包含什么类型的对象,因此它在内部使用 Object。对象数组不能转换为另一种类型的数组。如果将类类型传递给 Array 构造函数,那么它将知道类型,并且可以在内部使用 Ball 数组而不是 Object。使用 balls=new SnapshotArray(Ball.class);
    • 此方法会因ClassCastException 而崩溃。 github.com/libgdx/libgdx/issues/5076
    • @Sergey 这不是错误。正如 Array 的 javadocs 解释(以及我在上面的评论),如果您希望后备数组是 Object[] 以外的类型,则必须将 Class 显式传递给适当的构造函数。
    猜你喜欢
    • 2022-03-19
    • 2017-11-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 2012-03-29
    • 2012-03-14
    • 2011-11-23
    • 2020-10-21
    相关资源
    最近更新 更多