1

我有一个粒子“引擎”,我已经实现了一个池系统,并且我测试了两种不同的方式来渲染列表中的每个粒子。请注意,Pooling 确实与问题无关。当我注意到它们的行为不同时,我只是按照教程并尝试使用第二种方法。

第一种方式:

            for (int i = 0; i < particleList.size(); i++) {
            Iterator<Particle> it = particleList.iterator();
            while (it.hasNext()) {
                Particle p = it.next();
                if (p.isDead()){
                    it.remove();
                }

                p.render(batch, delta);
            }
        }

哪个工作得很好。我的粒子很锋利,它们以正确的速度移动。

第二种方式:

            Particle p;
        for (int i = 0; i < particleList.size(); i++) {
            p = particleList.get(i);
            p.render(batch, delta);

            if (p.isDead()) {
                particleList.remove(i);
                bulletPool.free(p);
            }

        }

这使我所有的粒子都变得模糊并且移动非常缓慢!

我的粒子的渲染方法如下所示:

    public void render(SpriteBatch batch, float delta) {
    sprite.setX(sprite.getX() + (dx * speed) * delta * Assets.FPS);
    sprite.setY(sprite.getY() + (dy * speed) * delta * Assets.FPS);
    ttl--;
    sprite.setScale(sprite.getScaleX() - 0.002f);

    if (ttl <= 0 || sprite.getScaleX() <= 0)
        isDead = true;

    sprite.draw(batch);
}

为什么不同的渲染方法会提供不同的结果?

提前致谢

4

1 回答 1

2

您在迭代列表时正在改变(从中删除元素)列表。这是制造混乱的经典方法。

Iterator必须具有正确处理删除案例的代码。但是您的基于索引的for循环没有。特别是当您调用时particleList.remove(i)i现在与列表的内容“不同步”。考虑一下当您删除索引 3 处的元素时会发生什么:“i”将递增到 4,但旧元素 4 被洗牌到索引 3,因此它将被跳过。

我假设您正在避免Iterator避免内存分配。因此,回避这个问题的一种方法是反转循环(从particleList.size()下降到 0)。或者,您只能增加i非死粒子。

于 2013-07-29T23:32:39.373 回答