Exemple #1
0
bool Collision::PixelPerfectTest(const sf::Sprite& Object1, const sf::Sprite& Object2, sf::Uint8 AlphaLimit) {
        //Get AABBs of the two sprites
    sf::IntRect Object1AABB = GetAABB(Object1);
    sf::IntRect Object2AABB = GetAABB(Object2);

    sf::IntRect Intersection;

    if (Object1AABB.Intersects(Object2AABB, &Intersection)) {

        //We've got an intersection we need to process the pixels
        //In that Rect.

        //Bail out now if AlphaLimit = 0
        if (AlphaLimit == 0) return true;

        //There are a few hacks here, sometimes the TransformToLocal returns negative points
        //Or Points outside the image.  We need to check for these as they print to the error console
        //which is slow, and then return black which registers as a hit.

        sf::IntRect O1SubRect = Object1.GetSubRect();
        sf::IntRect O2SubRect = Object2.GetSubRect();

        sf::Vector2i O1SubRectSize(O1SubRect.GetWidth(), O1SubRect.GetHeight());
        sf::Vector2i O2SubRectSize(O2SubRect.GetWidth(), O2SubRect.GetHeight());

        sf::Vector2f o1v;
        sf::Vector2f o2v;
        //Loop through our pixels
        for (int i = Intersection.Left; i < Intersection.Right; i++) {
            for (int j = Intersection.Top; j < Intersection.Bottom; j++) {

                o1v = Object1.TransformToLocal(sf::Vector2f(i, j)); //Creating Objects each loop :(
                o2v = Object2.TransformToLocal(sf::Vector2f(i, j));

                //Hack to make sure pixels fall withint the Sprite's Image
                if (o1v.x > 0 && o1v.y > 0 && o2v.x > 0 && o2v.y > 0 &&
                        o1v.x < O1SubRectSize.x && o1v.y < O1SubRectSize.y &&
                        o2v.x < O2SubRectSize.x && o2v.y < O2SubRectSize.y) {

                    //If both sprites have opaque pixels at the same point we've got a hit
                    if ((Object1.GetPixel(static_cast<int> (o1v.x), static_cast<int> (o1v.y)).a > AlphaLimit) &&
                            (Object2.GetPixel(static_cast<int> (o2v.x), static_cast<int> (o2v.y)).a > AlphaLimit)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    return false;
}