Search code examples
c++sfml

How do I do collision between two RectangleShapes in SFML 2.5.0? (C++)


So I'm relatively new to coding in SFML, so apologies if I made some newbie mistake. My project is Space Invaders in SFML. When I was working on the shooting, a problem arose. How do I do collision? I was familiar with shape.getGlobalBounds().intersect(), and it worked on previous projects. It didn't work. So I tried simplifying it. I used RectangleShape for both the enemy shape, and the bullet shape.

Here is the actual for loop, for the collision:

for (int y = 0; y <= 2; ++y) {
    for (int x = 0; x <= 6; ++x) {
        if (shootShape.getPosition().x < e.aliensX[x] && shootShape.getPosition().x > e.aliensX[x] + 15 ||
            shootShape.getPosition().y < e.aliensY[y] && shootShape.getPosition().y > e.aliensY[y] + 15) {
            e.aliensX[x] = -10;
            e.aliensY[y] = -10;
            shooting = false;
            reload = false;
        }
    }
}

This is the shooting function:

void Player::shoot() {
    if (reload) {
        shootX = posX + 5;
        shootY = posY - 50;
        shootShape.setPosition(shootX, shootY);
        shooting = true;
        reload = false;
    }
    if (shooting) {
        shootY -= 150 * 2 * deltaTime;
        shootShape.setPosition(shootX, shootY);
    }
}

And this is how I draw the enemies (I don't know how to create multiple enemies):

void Enemy::drawAliens() {
    for (int j = 0; j <= arraySizeY; ++j) {
        for (int i = 0; i <= arraySizeX; ++i) {
            actualShape.setPosition(aliensX[i], aliensY[j]);
            if (aliensY[i] <= p.shootY && aliensY[i] >= p.shootY) {
                aliensX[i] = -10;
                aliensY[i] = -10;
            }
            else {
                win.draw(actualShape);
            }
        }
    }
}

Explanation behind some of the variables: aliensX is an array which contains the different x positions for the enemies. aliensY is an array which contains the different y positions for the enemies. shooting is a bool variable, which is true when the bullet is travelling. reload is whether you can shoot.

EDIT: Intersect will not work because of the way I created my enemies. They are all in ONE shape. I need it to work with specific coordinates, because I don't know a better way to create multiple enemies all at once. If there is a way to do that, advice would be appreciated!


Solution

  • It's rather easy, if you rely on SFML's templated sf::Rect class. Just retrieve the rectangle for both objects as global boundaries and try to intersect them:

    const bool collides = firstDrawable.getGlobalBounds().intersect(secondDrawable.getGlobalBounds());`
    

    Same can be done with a small temporary rectangle you can fill with dynamic values not directly associated with a sf::Drawable:

    const sf::FloatRect bullet(x - width / 2, y - height / 2, width, height);
    const bool collides = firstDrawable.getGlobalBounds().intersect(bullet);`