Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: How to use "Simple Collision Detection?"  (Read 10433 times)

0 Members and 3 Guests are viewing this topic.

Girby2K11

  • Newbie
  • *
  • Posts: 24
    • View Profile
How to use "Simple Collision Detection?"
« on: April 30, 2011, 01:26:44 am »
Hi, i am am so new to sfml, i can make my sprites move but i now need collision detection but i can't figure out how to use it. heres the code in my project, but i get a bunch of errors which is very frustrating.

Code: [Select]
#include <SFML\Graphics.hpp>
#include <Collision.h>

int main()
{

     sf::RenderWindow App(sf::VideoMode(800, 600, 32), "SFML Failing");

     sf::Image iCharacter;
     if (!iCharacter.LoadFromFile("character.png"))
     return EXIT_FAILURE;
     sf::Sprite Object1(iCharacter);

     sf::Image iBall;
     if (!iBall.LoadFromFile("Ball.png"))
     return EXIT_FAILURE;

     sf::Sprite Object2(iBall);


     while (App.IsOpened())
     {
         sf::Event Event;

         while (App.GetEvent(Event))
         {
             if (Event.Type == sf::Event::Closed)
             App.Close();

             if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
             App.Close();
         }


         float ElapsedTime = App.GetFrameTime();

         if (App.GetInput().IsKeyDown(sf::Key::Right)) Object1.Move(100 * ElapsedTime, 0);
         if (App.GetInput().IsKeyDown(sf::Key::Left)) Object1.Move(-100 * ElapsedTime, 0);
         if (App.GetInput().IsKeyDown(sf::Key::Up)) Object1.Move( 0, -100 * ElapsedTime);
         if (App.GetInput().IsKeyDown(sf::Key::Down)) Object1.Move(0, 100 * ElapsedTime);

         Collision::BoundingBoxTest(Object1, Object2);

         App.Clear(sf::Color::Red);
         App.Draw(Object2);

         App.Draw(Object1);
        App.Display();
     }


    return EXIT_SUCCESS;
}


I have added collision.cpp to my project, but still get errors saying "Expected primary expression before &.

Please can someone help /  :?
I'm tring to learn SFML Help? Collision?

Dimple

  • Newbie
  • *
  • Posts: 30
    • View Profile
How to use "Simple Collision Detection?"
« Reply #1 on: April 30, 2011, 11:45:53 am »
This works for me:
Code: [Select]

#include <SFML/Graphics.hpp>
#include "Collision.h"

int main()
{

     sf::RenderWindow App(sf::VideoMode(800, 600, 32), "SFML Failing");

     sf::Image iCharacter;
     if (!iCharacter.LoadFromFile("character.png"))
     return EXIT_FAILURE;
     sf::Sprite Object1(iCharacter);

     Object1.SetPosition(100.f,100.f);

     sf::Image iBall;
     if (!iBall.LoadFromFile("Ball.png"))
     return EXIT_FAILURE;

     sf::Sprite Object2(iBall);

     Object2.SetPosition(300.f,300.f);

     while (App.IsOpened())
     {
         sf::Event Event;

         while (App.GetEvent(Event))
         {
             if (Event.Type == sf::Event::Closed)
             App.Close();

             if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
             App.Close();
         }


         float ElapsedTime = App.GetFrameTime();

         if (App.GetInput().IsKeyDown(sf::Key::Right)) Object1.Move(100 * ElapsedTime, 0);
         if (App.GetInput().IsKeyDown(sf::Key::Left)) Object1.Move(-100 * ElapsedTime, 0);
         if (App.GetInput().IsKeyDown(sf::Key::Up)) Object1.Move( 0, -100 * ElapsedTime);
         if (App.GetInput().IsKeyDown(sf::Key::Down)) Object1.Move(0, 100 * ElapsedTime);

         if(Collision::BoundingBoxTest(Object1, Object2)) {

             return EXIT_SUCCESS;
         }

         App.Clear(sf::Color::Red);
         App.Draw(Object2);

         App.Draw(Object1);
        App.Display();
     }


    return EXIT_SUCCESS;
}

Copy and paste the exact error messages.

Girby2K11

  • Newbie
  • *
  • Posts: 24
    • View Profile
How to use "Simple Collision Detection?"
« Reply #2 on: April 30, 2011, 12:15:00 pm »
Quote from: "Dimple"
This works for me:
Code: [Select]

#include <SFML/Graphics.hpp>
#include "Collision.h"

int main()
{

     sf::RenderWindow App(sf::VideoMode(800, 600, 32), "SFML Failing");

     sf::Image iCharacter;
     if (!iCharacter.LoadFromFile("character.png"))
     return EXIT_FAILURE;
     sf::Sprite Object1(iCharacter);

     Object1.SetPosition(100.f,100.f);

     sf::Image iBall;
     if (!iBall.LoadFromFile("Ball.png"))
     return EXIT_FAILURE;

     sf::Sprite Object2(iBall);

     Object2.SetPosition(300.f,300.f);

     while (App.IsOpened())
     {
         sf::Event Event;

         while (App.GetEvent(Event))
         {
             if (Event.Type == sf::Event::Closed)
             App.Close();

             if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
             App.Close();
         }


         float ElapsedTime = App.GetFrameTime();

         if (App.GetInput().IsKeyDown(sf::Key::Right)) Object1.Move(100 * ElapsedTime, 0);
         if (App.GetInput().IsKeyDown(sf::Key::Left)) Object1.Move(-100 * ElapsedTime, 0);
         if (App.GetInput().IsKeyDown(sf::Key::Up)) Object1.Move( 0, -100 * ElapsedTime);
         if (App.GetInput().IsKeyDown(sf::Key::Down)) Object1.Move(0, 100 * ElapsedTime);

         if(Collision::BoundingBoxTest(Object1, Object2)) {

             return EXIT_SUCCESS;
         }

         App.Clear(sf::Color::Red);
         App.Draw(Object2);

         App.Draw(Object1);
        App.Display();
     }


    return EXIT_SUCCESS;
}

Copy and paste the exact error messages.


For some reason i can't see my character and ball. Actually i can see the objects now but the program quickly starts then ends when i add if(Collision::BoundingBoxTest(Object1, Object2))
         return EXIT_FAILURE;
I'm tring to learn SFML Help? Collision?

Dimple

  • Newbie
  • *
  • Posts: 30
    • View Profile
How to use "Simple Collision Detection?"
« Reply #3 on: April 30, 2011, 12:35:49 pm »
Quote from: "Girby2K11"

For some reason i can't see my character and ball. Actually i can see the objects now but the program quickly starts then ends when i add if(Collision::BoundingBoxTest(Object1, Object2))
         return EXIT_FAILURE;

Are the objects on top of each other in the beginning? I added that part only to test if the detection worked. It causes the program to exit if the sprites are on top of each other.

Girby2K11

  • Newbie
  • *
  • Posts: 24
    • View Profile
How to use "Simple Collision Detection?"
« Reply #4 on: April 30, 2011, 12:37:48 pm »
Quote from: "Dimple"
Quote from: "Girby2K11"

For some reason i can't see my character and ball. Actually i can see the objects now but the program quickly starts then ends when i add if(Collision::BoundingBoxTest(Object1, Object2))
         return EXIT_FAILURE;

Are the objects on top of each other in the beginning? I added that part only to test if the detection worked. It causes the program to exit if the sprites are on top of each other.


No, i just deleted if(Collision::BoundingBoxTest(Object1, Object2))
         return EXIT_FAILURE; and when i compiled the objects were not touching.
I'm tring to learn SFML Help? Collision?

Dimple

  • Newbie
  • *
  • Posts: 30
    • View Profile
How to use "Simple Collision Detection?"
« Reply #5 on: April 30, 2011, 12:49:59 pm »
If adding that causes the program exit, it means that the function returns true so there should be a collision. Try to put the sprites further away from each other. Put them on opposite edges of the screen.

Girby2K11

  • Newbie
  • *
  • Posts: 24
    • View Profile
How to use "Simple Collision Detection?"
« Reply #6 on: April 30, 2011, 12:51:37 pm »
Quote from: "Dimple"
If adding that causes the program exit, it means that the function returns true so there should be a collision. Try to put the sprites further away from each other. Put them on opposite edges of the screen.


Or should i put the character off the screen but then use the keys to control him back in the view?
I'm tring to learn SFML Help? Collision?

Dimple

  • Newbie
  • *
  • Posts: 30
    • View Profile
How to use "Simple Collision Detection?"
« Reply #7 on: April 30, 2011, 01:06:17 pm »
It doesn't matter whether the objects are on the screen or not, the detection works exactly the same. I wanted you to put them far from each other so that you could see if the program closes no matter where the objects are (ie. the collision detection function doesn't work).

Girby2K11

  • Newbie
  • *
  • Posts: 24
    • View Profile
How to use "Simple Collision Detection?"
« Reply #8 on: April 30, 2011, 01:07:59 pm »
Quote from: "Dimple"
It doesn't matter whether if the objects are on the screen or not, the detection works exactly the same. I wanted you to put them far from each other so that you could see if the program closes no matter where the objects are (ie. the collision detection function doesn't work).


Ok i have just moved the characters to the end of the screen and the program doesn't shut, but the bounding box is so big, cant i resize it? And not make the program close but make the object move not collide?
I'm tring to learn SFML Help? Collision?

Dimple

  • Newbie
  • *
  • Posts: 30
    • View Profile
How to use "Simple Collision Detection?"
« Reply #9 on: April 30, 2011, 01:20:43 pm »
You can't manually set the size of the bounding box without modifying the BoundingBoxTest-function (unless there's something you can do with the sprites themselves that I'm not aware of). What are the dimensions of your images?

Do you need to rotate the sprites btw? If not then writing your own detection function is really easy.

Girby2K11

  • Newbie
  • *
  • Posts: 24
    • View Profile
How to use "Simple Collision Detection?"
« Reply #10 on: April 30, 2011, 01:36:05 pm »
Quote from: "Dimple"
You can't manually set the size of the bounding box without modifying the BoundingBoxTest-function (unless there's something you can do with the sprites themselves that I'm not aware of). What are the dimensions of your images?

Do you need to rotate the sprites btw? If not then writing your own detection function is really easy.


I think i would prefer to make my own collision, is it possible if you could't write a collision detection and ill input it on my code and see if it works?
I'm tring to learn SFML Help? Collision?

Dimple

  • Newbie
  • *
  • Posts: 30
    • View Profile
How to use "Simple Collision Detection?"
« Reply #11 on: April 30, 2011, 01:48:16 pm »
Here's one that I wrote in maybe two minutes. I'll try to explain it to you later (gotta go right now) but the idea is exactly the same that I tried to explain to you in the other thread.

Add this before your main-function
Code: [Select]

static bool checkCollision(sf::Sprite sprite1, sf::Sprite sprite2) {

    if(sprite1.GetPosition().x  + sprite1.GetSize().x > sprite2.GetPosition().x && sprite1.GetPosition().x < sprite2.GetPosition().x + sprite2.GetSize().x && sprite1.GetPosition().y + sprite1.GetSize().y > sprite2.GetPosition().y && sprite1.GetPosition().y < sprite2.GetPosition().y + sprite2.GetSize().y)
        return true;

    return false;
}

It's used like this
Code: [Select]
if(checkCollision(Object1, Object2))
             std::cout << "Collision!";

Girby2K11

  • Newbie
  • *
  • Posts: 24
    • View Profile
How to use "Simple Collision Detection?"
« Reply #12 on: April 30, 2011, 01:50:13 pm »
Quote from: "Dimple"
Here's one that I wrote in maybe two minutes. I'll try to explain it to you later (gotta go right now) but the idea is exactly the same that I tried to explain to you in the other thread.

Add this before your main-function
Code: [Select]

static bool checkCollision(sf::Sprite sprite1, sf::Sprite sprite2) {

    if(sprite1.GetPosition().x  + sprite1.GetSize().x > sprite2.GetPosition().x && sprite1.GetPosition().x < sprite2.GetPosition().x + sprite2.GetSize().x && sprite1.GetPosition().y + sprite1.GetSize().y > sprite2.GetPosition().y && sprite1.GetPosition().y < sprite2.GetPosition().y + sprite2.GetSize().y)
        return true;

    return false;
}

It's used like this
Code: [Select]
if(checkCollision(Object1, Object2))
             std::cout << "Collision!";


OK thanks, you are really helping me out i appreciate this.
I'm tring to learn SFML Help? Collision?

Dimple

  • Newbie
  • *
  • Posts: 30
    • View Profile
How to use "Simple Collision Detection?"
« Reply #13 on: May 02, 2011, 06:15:29 pm »
OK, I'll try to go the function through in detail now (had a busy weekend :P).
Code: [Select]

static bool checkCollision(sf::Sprite sprite1, sf::Sprite sprite2) {

     if(sprite1.GetPosition().x  + sprite1.GetSize().x > sprite2.GetPosition().x && sprite1.GetPosition().x < sprite2.GetPosition().x + sprite2.GetSize().x && sprite1.GetPosition().y + sprite1.GetSize().y > sprite2.GetPosition().y && sprite1.GetPosition().y < sprite2.GetPosition().y + sprite2.GetSize().y)
         return true;

     return false;
 }

The idea is very simple: compare the coordinates to determine whether the rectangle around the sprite is on top of the other sprite's rectangle. To do that I actually rule out all the possibilities how the rectangles could be positioned so that they aren't overlapping. If they can be ruled out, the rectangles are on top of each other.

The rectangle is formed using the sprite's coordinates and the sprite's size. So the upper left corner of sprite1's rectangle is at (sprite1.GetPosition().x, sprite1.GetPosition().y), right upper corner is at (sprite1.GetPosition().x + sprite1.GetSize().x, sprite1.GetPosition().y), left lower corner is at (sprite1.GetPosition().x + sprite1.GetSize().x, sprite1.GetPosition().y) and the lower right corner is at (sprite1.GetPosition().x + sprite1.GetSize().x, sprite1.GetPosition().y + sprite1.GetSize().x). The same is done for sprite2.

Now that we have formed the rectangles we only need to figure out whether they are on top of each other or not. Let's go through the x-axis first. The rectangles can't possibly be on top of each other if the sprite1 is too far to the left from sprite2 (ie. "the right side" of the sprite1's rectangle is on the left of "the left side" of the sprite2's rectangle). So we want to compare
Code: [Select]

sprite1.GetPosition().x  + sprite1.GetSize().x

with
Code: [Select]

sprite2.GetPosition().x

to rule out the possibility that the sprite1 would be too far to the left for the rectangles to collide. So in code it looks like this:
Code: [Select]

if(sprite1.GetPosition().x  + sprite1.GetSize().x > sprite2.GetPosition().x)

Now if the sprite1 is too far to the left, that expression is false (a collision isn't possible). Now the same is done for the other side: we rule out the possibility that the sprite1 is too far to the right from the sprite2.
Code: [Select]

if(sprite1.GetPosition().x < sprite2.GetPosition().x + sprite2.GetSize().x)

Combining the two we get:
Code: [Select]

if(sprite1.GetPosition().x  + sprite1.GetSize().x > sprite2.GetPosition().x && sprite1.GetPosition().x < sprite2.GetPosition().x + sprite2.GetSize().x)

Which already works for the x-axis. The only thing left is to do the same with the y-axis and the function is complete. It's exactly the same thing: you can actually copy and paste the first part and just change the x's to y's and that's it.

I hope I got everything about right. Ask if you didn't understand something. Oh, and if you want some help with what to do with the information that the objects are indeed colliding, tell me what would you would want to happen when the collision occurs and I can help you implement it.

Girby2K11

  • Newbie
  • *
  • Posts: 24
    • View Profile
How to use "Simple Collision Detection?"
« Reply #14 on: May 02, 2011, 06:40:33 pm »
Hope you had a great weekend  :D So with this collision detection how would I actually be able to make the sprite not move any further once it has hit the rectangle? I have tried
Code: [Select]
sprite1.move(speed * ElapsedTime, 0); but it only goes left(I think) but I want the whole box to be protected.
I'm tring to learn SFML Help? Collision?