Пример #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;
}
Пример #2
0
bool Bullet::detectCollision(sf::Vector2f p, const sf::Sprite& sprite) const
{
    /* collide if the pixel is not transparent */
    int img_width = sprite.GetSize().x, img_height = sprite.GetSize().y;
    int img_x = pos.x - p.x + img_width / 2, img_y = pos.y - p.y + img_height / 2;
    if (img_x < 0 || img_x >= img_width)
        return false;
    if (img_y < 0 || img_y >= img_height)
        return false;
    return sprite.GetPixel(img_x, img_y).a != 0;
}
Пример #3
0
/*!
 * \brief Tests whether the sprite Obj1 collides with the sprite Obj2
 * \param Obj1 The first of the two objects
 * \param Obj2 The second of the two objects
 * \param AlphaLimit The limit of the alpha value
 * \return Are the two objects are in collision (via a pixel-perfect method) ?
 *
 * It tests using a pixel-perfect condition, with AlphaLimit to test whether
 * the pixels are colliding.
 */
bool Collision::PixelTest(const sf::Sprite &Obj1, const sf::Sprite &Obj2,
                          sf::Uint8 AlphaLimit)
{
    sf::IntRect Obj1BoundingBox(GetBoundingBox(Obj1));
    sf::IntRect Obj2BoundingBox(GetBoundingBox(Obj2));

    sf::IntRect Intersection;

    if (!Obj1BoundingBox.Intersects(Obj2BoundingBox, &Intersection))
        return false;

    if (AlphaLimit == 0)
        return true;

    for (int I = Intersection.Left ; I <= Intersection.Right ; ++I)
    {
        for (int J = Intersection.Top ; J <= Intersection.Bottom ; ++J)
        {
            sf::Vector2i Obj1Pix(I - Obj1BoundingBox.Left, J
                    - Obj1BoundingBox.Top);
            sf::Vector2i Obj2Pix(I - Obj2BoundingBox.Left, J
                    - Obj2BoundingBox.Top);

            if (Obj1Pix.x >= 0 && Obj1Pix.x < Obj1BoundingBox.GetWidth()
                    && Obj1Pix.y >= 0 && Obj1Pix.y
                    < Obj1BoundingBox.GetHeight() && Obj2Pix.x >= 0
                    && Obj2Pix.x < Obj2BoundingBox.GetWidth() && Obj2Pix.y >= 0
                    && Obj2Pix.y < Obj2BoundingBox.GetHeight()
                    && Obj1.GetPixel(Obj1Pix.x, Obj1Pix.y).a > AlphaLimit
                    && Obj2.GetPixel(Obj2Pix.x, Obj2Pix.y).a > AlphaLimit)
                return true;
        }
    }

    return false;
}