1

So I recently got into SFML programming, and I need help creating a bool that checks if two rectangles are colliding or overlapping each other.

This is the code so far:

     bool collision(sf::Rect rect, sf::Rect rect2){
            return rect.getGlobalBounds().intersects(rect2.getGlobalBounds());
     }

I'm receiving these errors:

  • missing template arguments before 'rect'
  • missing template arguments before 'rect2'
  • expected primary-expression before ')' token

I am making a platformer and cannot find an efficient way to test collision between the player and the world.

This is the kind of code I want to write for this simple program:

if(collision(rectangle1,rectangle2)){
std::cout << "collision" << std::endl;
}

Any help is appreciated! :)

Here is my code:

#include <SFML/Graphics.hpp>
#include <SFML/Window/Keyboard.hpp>
#include <SFML/Graphics/Rect.hpp>

int main(){
    sf::RenderWindow window(sf::VideoMode(800,600),"INSERT_WINDOW_TITLE", sf::Style::Titlebar | sf::Style::Close);
    sf::RectangleShape rect1(sf::Vector2f(20.f,20.f));
    rect1.setFillColor(sf::Color::Blue);
    sf::RectangleShape rect2(sf::Vector2f(20.f,20.f));
    rect2.setFillColor(sf::Color::Green);

    bool collision(sf::FloatRect r1, sf::FloatRect r2)
    {
        return r1.intersects(r2, sf::FloatRect());
    }

    while(window.isOpen()){
        sf::Event event;

        while(window.pollEvent(event)){
             if (event.type == sf::Event::Closed)
                window.close();
        }
        if(sf::Keyboard::isKeyPressed(sf::KeyBoard::W) && collision(rect1,rect2) == false) rect1.move(0.f,-1.f);
        if(sf::Keyboard::isKeyPressed(sf::KeyBoard::S) && collision(rect1,rect2) == false) rect1.move(0.f,1.f);
        if(sf::Keyboard::isKeyPressed(sf::KeyBoard::A) && collision(rect1,rect2) == false) rect1.move(-1.f,0.f);
        if(sf::Keyboard::isKeyPressed(sf::KeyBoard::D) && collision(rect1,rect2) == false) rect1.move(1.f,0.f);

        window.draw(rect1);
        window.draw(rect2);
        window.display();
    }
}
A. Kim
  • 102
  • 2
  • 9
  • 1
    `sf::Rect` is a template, so you need to specify which data type it holds. For example `sf::Rect`. – super Nov 25 '18 at 20:57

1 Answers1

3

Rect is a class template, not an actual class. There are predefined typedefs called IntRect and FloatRect for Rect<int> and Rect<float> respectively. You want to use one of those:

bool collision(sf::FloatRect r1, sf::FloatRect r2)
{
    sf::FloatRect intersection;
    return r1.intersects(r2, intersection);
}

UPDATE:

Here's a "fixed" version of your code. I added an overload that takes Shapes and forwards to the Rect collision-checking function. I also repositioned your rect2 rectangle; otherwise you cannot move as you already have a collision.

#include <SFML/Graphics.hpp>
#include <SFML/Window/Keyboard.hpp>

    bool collision(sf::FloatRect r1, sf::FloatRect r2)
    {
        sf::FloatRect intersection;
        return r1.intersects(r2, intersection);
    }

bool collision(sf::Shape const & r1, sf::Shape const & r2)
{
    return collision(r1.getGlobalBounds(), r2.getGlobalBounds());
}

int main(){
    sf::RenderWindow window(sf::VideoMode(800,600),"INSERT_WINDOW_TITLE", sf::Style::Titlebar | sf::Style::Close);
    sf::RectangleShape rect1(sf::Vector2f(20.f,20.f));
    rect1.setFillColor(sf::Color::Blue);
    sf::RectangleShape rect2(sf::Vector2f(20.f,20.f));
    rect2.setFillColor(sf::Color::Green);
    rect2.setPosition(100.f, 100.f);

    while(window.isOpen()){
        sf::Event event;

        while(window.pollEvent(event)){
             if (event.type == sf::Event::Closed)
                window.close();
        }
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::W) && collision(rect1,rect2) == false) rect1.move(0.f,-1.f);
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::S) && collision(rect1,rect2) == false) rect1.move(0.f,1.f);
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::A) && collision(rect1,rect2) == false) rect1.move(-1.f,0.f);
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::D) && collision(rect1,rect2) == false) rect1.move(1.f,0.f);

        window.clear();
        window.draw(rect1);
        window.draw(rect2);
        window.display();
    }
}

Note that there are other issues here as well; e.g. your game loop runs as fast as possible right now, which is probably not what you want. This code does run, though.

ravnsgaard
  • 922
  • 1
  • 10
  • 20
  • That didn't work. I tried to use it, but received an error: a function-definition is not allowed here before '{' token – A. Kim Nov 26 '18 at 00:53
  • 1
    That means your code structure is messed up. Try to post or link to the complete file... – ravnsgaard Nov 26 '18 at 06:47
  • Could you please provide an example including an if-statement showing how it is used? Just use rect1 and rect2 as the example, or something similar. – A. Kim Nov 27 '18 at 20:56
  • There are several problems with your code. First of all, you cannot declare a function inside another function, except by using lambdas. If you move the definition of `collision` out of `main` that solves *that* error. But it still won't work, because you don't actually have `sf::Rect`s to compare, you have `sf::RectangleShape`s, which is very different. You can get the needed `Rect`s by calling `getGlobalBounds()` on your shapes. Finally, you need to reposition one of the rectangles first (you are drawing them at the same place), and you need to call `window.clear()` before you draw them. – ravnsgaard Nov 28 '18 at 00:09
  • Interestingly, you original code was *almost* correct. You should have used parameters of type `RectangleShape` instead of `Rect`. This is the very reason why you should always post a [minimal, complete, and verifiable example](https://stackoverflow.com/help/mcve). – ravnsgaard Nov 28 '18 at 00:18
  • I updated the answer to include a "working" version. – ravnsgaard Nov 28 '18 at 09:03
  • Thanks! That worked! And I'm sorry for the abundance of questions, I am just a hobbyist and didn't receive an education at a college or anything... Again, thank you. – A. Kim Nov 29 '18 at 00:53
  • @A.Kim Neither did I, to tell you the truth. I *did* read a lot of [books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) on the subject, though. I recommend you do the same. :-) – ravnsgaard Nov 29 '18 at 01:01