有效地找到位图中像素的值?

时间:2014-06-04 01:12:46

标签: android performance bitmap game-engine

所以,我编写了一个游戏,你可以向敌人射击子弹。我目前正在设计命中检测方法,它涉及每个子弹和敌人(它们本身是使用Paths绘制的复杂形状)获得自己的缩小位图(bulletMask []和enemyMask []),使用ALPHA_8配置0 alpha意味着什么都没有,255 alpha意味着那里有东西。

位图都被绘制得很好,绘图操作也很好。但是,当我需要检查哪些子弹与哪些敌人交叉时,我会得到巨大的延迟,大约300-400毫秒。现在,原因是因为我采用蛮力方法来检测命中。以下是涉及的循环:

    for (int y = 0; y < height / 8; y++) {
        for (int x = 0; x < width / 8; x++) {
            for (int i = 0; i < MAX_ENEMIES; i++) {
                for (int j = 0; j < MAX_BULLETS; j++) {
                    if (bulletMask[j].getPixel(x, y) != 0 && enemyMask[i].getPixel(x, y) != 0) {
                        enemy[ALIVE][i] = 0;
                        bullet[ALIVE][j] = 0;
                    }
                }
            }
        }
    }

所以基本上,它遍历每个像素,并检查是否有任何敌人像素与任何子弹像素相交。如果是的话,子弹和像素都会消失。

MAX_ENEMIES为10,MAX_BULLETS为5,而每个Bitmap中的像素数为32400,这意味着此循环每帧必须重复162万次。我还没有开始编写除此强力算法之外的任何代码,但我有一种感觉,如果我找不到解决方案,我将需要设计更复杂的东西。

我只需要一种更有效的查找像素的方法,或至少比较位图之间的像素。在上面的代码中编辑if块可以使游戏正常运行。

2 个答案:

答案 0 :(得分:3)

彼此内部的4个循环确实很糟糕。看起来像O(n²)。

您可能想要做的第一件事是将位图转换为int-Arrays。如果您使用的是BufferedImage,那么getRGB就可以了。

其次,你不应该那样蛮力。像迭代子弹然后检查它们占据的像素一样会给你带来巨大的性能提升。

答案 1 :(得分:2)

如果您知道每个子弹和敌人的位置,您可以使用数学方法,无需任何像素检查,通过半径测试比较子弹与敌人,看看它们是否相交。

例如,如果子弹的中心与敌人的中心之间的距离小于两者的半径之和,则表示存在碰撞。

或者代替半径测试,您可以为每个命中区域矩形指定矩形,并检查矩形是否相交。

如果您需要像素完美碰撞,您可以简单地遍历每个子弹周围的像素并检查敌人是否在他们的区域内。假设子弹的面积为50像素,这意味着只检查所有5个子弹和10个敌人的2500像素(最多)。

你甚至可以将这两种方法结合起来,做半径/矩形测试作为初步检查,只有在成功的情况下,循环遍历像素,尽管可能没有必要。

一旦你知道敌人已经死亡或子弹已用完,你也应该突破循环,而不是继续计算。