两个物体形状的命中测试

Hittest for two object shapes

假设我们有一个具有任意复杂形状的 Hitbox 的对象和一个具有 circle/polygon 作为 Hitbox 的对象。如何检测这两个对象(不是边界矩形,而是实际像素)的碰撞?两个对象都是不透明的 Sprites。

试试这个。纹理精灵来自 Flambe 引擎。本质上是碰撞的边界框,然后遍历碰撞框检查每个像素。

    static public function pixelPerfect(sprite1:SpriteContainer, sprite2:SpriteContainer):Bool
    {
        var collisionRect:Rectangle;

        for (texture1 in sprite1.textures)
        {
            for (texture2 in sprite2.textures)
            {
                collisionRect = CollisionUtil.collisionRect(texture1, texture2);
                if (collisionRect == null) continue;

                if (pixelCollision(texture1, collisionRect) && pixelCollision(texture2, collisionRect))
                {
                    return true;
                }
            }
        }

        return false;
    }

static public function pixelCollision(sprite:TextureSprite, collisionRect:Rectangle) 
    {
        var localRectPt:Point = sprite.globalToLocal(collisionRect.x, collisionRect.y);
        localRectPt.x /= Main.GLOBAL_SCALE;
        localRectPt.y /= Main.GLOBAL_SCALE;

        var scaledRect:Rectangle = collisionRect.clone();
        scaledRect.width /= Main.GLOBAL_SCALE;
        scaledRect.height /= Main.GLOBAL_SCALE;

        var PIXEL_DATA_LENGTH:Int = 4;
        var PIXELS_TO_SKIP:Int = 5;
        var resolution:Int = PIXEL_DATA_LENGTH * PIXELS_TO_SKIP;
        var alphaOffset:Int = 3;
        var bytes:Bytes;
        try{
            bytes = sprite.symbol.atlas.readPixels(Math.round(localRectPt.x), Math.round(localRectPt.y), Math.round(scaledRect.width), Math.round(scaledRect.height));
            var n:Int = bytes.length;
            var i:Int = 0;
            while(i+3<n)
            {
                if (bytes.get(i + alphaOffset) > 0)
                {
                    return true;
                }

                i += resolution;
            }
        }
        catch (e:Dynamic)
        {
            Log.trace(e);
        }

        bytes = null;

        return false;
    }
}

这是我在 ActionScript 3 (https://snipplr.com/view/90435/pixel-perfect-collision-detection-as3/) 中找到的一段代码,看起来应该可以在 OpenFL 中运行。

代码的 Haxe 版本可能如下所示:

public function objectsHit (mc1:DisplayObject, mc2:DisplayObject):Bool {

    var mc1bounds = mc1.getBounds (this);
    var mc2bounds = mc2.getBounds (this);
    var allintersections = (mc2bounds.intersection(mc1bounds));

    for (xval in allintersections.x...(allintersections.x + allintersections.width)) {
        for (yval in allintersections.y...(allintersections.y + allintersections.height)) {
            if (mc2.hitTestPoint (xval, yval, true) && mc1.hitTestPoint (xval, yval, true)) {
                return true;
            }
        }
    }

    return false;
}

也可以先使用 hitTestObject 方法,然后再使用 hitTestPoint 方法。一般的想法是首先执行边界框命中检测,如果您需要更精确的东西,然后执行基于点的碰撞(这更昂贵)。