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

Author Topic: SFML collision detection  (Read 6992 times)

0 Members and 2 Guests are viewing this topic.

neobrain

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
SFML collision detection
« on: November 22, 2014, 05:06:58 am »
I am trying to develop maps like the ones in this game (1)

Well, my current algorithm could be hacky but I have a problem detecting  collisions.

I have the following code but apparently, I still have collisions like (2). I am not sure what is wrong with the code but it is surely not giving the expected results.

/*
 * Set the number of leafs dictated by the level, very simple implementation
 * that does not come up with as cute a maps Set the first leaf at the middle
 * of the map, for an even 'i' generate a random  x-coordinate while for an odd
 * 'i' generate a y-coordinate, check for overlap/collision, hack the coordinates
 * further if one exists
 */

leafenvironment::leafenvironment(int level) {
  srand(time(nullptr));
  for (size_t i = 0; i < level; i++) {
    lily *current = new lily();
    leafs.push_back(current);
  }
  // first lily at centre of window and redundant stuff
  for (size_t i = 0; i < level; i++) {
    if (i == 0) {
      pos *current = new pos;
      current->x = WIDTH / 2;
      current->y = HEIGHT / 2;
      position.push_back(current);
      assert(leafs[i]);
      leafs[i]->SetPosition(position[i]->x, position[i]->y);
      leafs[i]->GetSprite().setScale(0.5f, 0.5f);
      continue;
    }
 
    float newpos = static_cast<float>(rand() % 10);
    if (i % 2) {
      pos *current = new pos;
      current->x = newpos * 30;
      current->y = position[i - 1]->y;
      position.push_back(current);
      assert(leafs[i]);
      leafs[i]->SetPosition(position[i]->x, position[i]->y);
      leafs[i]->GetSprite().setScale(0.5f, 0.5f);
      for (size_t j = i - 1; j <= 0; j--) {
        while (leafs[i]->GetSprite().getGlobalBounds().intersects(leafs[j]->GetSprite().getGlobalBounds())) {
          leafs[i]->SetPosition(position[i]->x * 100, position[i]->y);
        }
      }
    } else {
      pos *current = new pos;
      current->x = position[i - 1]->x;
      current->y = newpos * 30;
      position.push_back(current);
      assert(leafs[i]);
      leafs[i]->SetPosition(position[i]->x, position[i]->y);
      leafs[i]->GetSprite().setScale(0.5f, 0.5f);
      for (size_t j = i - 1; j <= 0; j--) {
        while (leafs[i]->GetSprite().getGlobalBounds().intersects(leafs[j]->GetSprite().getGlobalBounds())) {
          leafs[i]->SetPosition(position[i]->x, position[i]->y * 100);
        }
      }
    }
  }
}
 

I think of developing an algorithm where I  use an a 2-d array to represent the window grid some thing like


#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>

char grid[15][16] = {
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0},
    {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',0}
};

int main()
{
    srand (time(NULL));

    int x = rand() % 15, y = rand() % 15;

    grid[x][y] = '@';

    for (int lily = 0; lily < 10; ++lily)
    {
        std::vector<std::pair<int,int>> avail;
        for (int ix = x+1; ix < 15; ++ix)
        {
            if (grid[ix][y] == '@')
            {
                break;
            }
            avail.push_back(std::make_pair(ix,y));
        }
        for (int ix = x-1; ix >= 0; --ix)
        {
            if (grid[ix][y] == '@')
            {
                break;
            }
            avail.push_back(std::make_pair(ix,y));
        }

        for (int iy = y+1; iy < 15; ++iy)
        {
            if (grid[x][iy] == '@')
            {
                break;
            }
            avail.push_back(std::make_pair(x,iy));
        }
        for (int iy = y-1; iy >= 0; --iy)
        {
            if (grid[x][iy] == '@')
            {
                break;
            }
            avail.push_back(std::make_pair(x,iy));
        }
        std::pair<int,int> xy = avail[rand() % avail.size()];
        x = xy.first;
        y = xy.second;
        grid[x][y] = '@';
    }

    for (int i = 0; i < 15; ++i)
    {
        std::cout << grid[i] << std::endl;
    }
}

but then I am stuck at how to map the filled array onto the window grid. Could someone please point me in the right direction?

1)http://www.psdevwiki.com/ps3/Scogger_HD
2)http://imgur.com/a/pBEyh

Gambit

  • Sr. Member
  • ****
  • Posts: 283
    • View Profile
Re: SFML collision detection
« Reply #1 on: November 22, 2014, 07:49:04 am »
This is not a help and support forum for broken code. Collision detection is outside the scope of a multimedia library (With the exception of FloatRect and IntRect), and is therefore irrelevant. This is also posted in the wrong category, it does not pertain to SFML-Graphics.

neobrain

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
Re: SFML collision detection
« Reply #2 on: November 22, 2014, 08:36:05 am »
This is not a help and support forum for broken code. This is also posted in the wrong category, it does not pertain to SFML-Graphics.

Did you even undertand my code Sir? or don't reply to the post if you don't understand. This code pertains sf :: Sprite.

Quote
Collision detection is outside the scope of a multimedia library (With the exception of FloatRect and IntRect)

Can't one use sf:: FloatRect to detect collision?

Gambit

  • Sr. Member
  • ****
  • Posts: 283
    • View Profile
Re: SFML collision detection
« Reply #3 on: November 23, 2014, 12:42:23 am »
Collision detection is not related to graphics, its purely logical. sf::Rect has ::contains and ::intersects and sf::Sprite has ::get(Global|Local)Bounds which returns sf::Rect. The fact that you can get an sf::Rect from an sf::Sprite does not make collision detection part of graphics.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: SFML collision detection
« Reply #4 on: November 23, 2014, 04:08:08 am »
Did you even undertand my code Sir? or don't reply to the post if you don't understand.
This sounds rather rude. Maybe you will reconsider your way of asking for help.

Your "question" does not really explain what exact problem you are experiencing.

It is imperative that you read this post immediately.

For example, complete and minimal code would be extremely useful here.

As for sf::Floatrect... It can inform you that two rectangles are overlapping or that a point is inside a rectangle (rectangles must be axis-aligned) but you must decide what to do with that information to reverse any collisions.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

neobrain

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
Re: SFML collision detection
« Reply #5 on: November 23, 2014, 05:39:41 am »
Did you even undertand my code Sir? or don't reply to the post if you don't understand.
This sounds rather rude. Maybe you will reconsider your way of asking for help.

Your "question" does not really explain what exact problem you are experiencing.

It is imperative that you read this post immediately.

For example, complete and minimal code would be extremely useful here.

As for sf::Floatrect... It can inform you that two rectangles are overlapping or that a point is inside a rectangle (rectangles must be axis-aligned) but you must decide what to do with that information to reverse any collisions.

The OP was obviously being rude may be because it was my first time to post here. Its obviously not good for one to not even read your post and then with a lot of confidence claim you are posting in the wrong place.

If I have two sf::FloatRect I am supposed to able to check their collision by checking whether they intersect.

That might not be very clear from the code but that is what I am doing on here.

 
   

while (leafs[i]->GetSprite().getGlobalBounds().intersects(leafs[j]->GetSprite().getGlobalBounds())) {
          leafs[i]->SetPosition(position[i]->x * 100, position[i]->y);
        }
     }
 

I am not sure I can detect collision before I draw the sprites, can  I?

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: SFML collision detection
« Reply #6 on: November 23, 2014, 07:47:34 am »
The OP [that's you, neobrain, by the way -Hapax] was obviously being rude may be because it was my first time to post here. Its obviously not good for one to not even read your post and then with a lot of confidence claim you are posting in the wrong place.
If you think someone may be incorrect, you are free to state why. That can be done without resorting to rudeness, especially if it is your first time posting; it would not be a good first impression.

It looks like Gambit actually did read your post. I do not think anything that was said was untrue.

Just so you know for the future, the Graphics forum is generally for discussion relating to the usage of the Graphics module of SFML.
Discussions about collision do not fit into that category just because a part of the module is used. It is merely the way that you store and display information.
If your problem is that you are having a problem using or understanding sf::FloatRects, this is a good place to mention that problem, but your question is not stating that that is the case, which is why being specific about what you're having a problem with is very useful.

If I have two sf::FloatRect I am supposed to able to check their collision by checking whether they intersect.
while (leafs[i]->GetSprite().getGlobalBounds().intersects(leafs[j]->GetSprite().getGlobalBounds()))
This does look like it should be okay to me.

leafs[i]->SetPosition(position[i]->x * 100, position[i]->y);
We can't be sure what "position" is; you haven't really told us.

I am not sure I can detect collision before I draw the sprites, can  I?
Yes, you can. It doesn't need to be drawn for you to be able to get their bounds.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

neobrain

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
Re: SFML collision detection
« Reply #7 on: November 23, 2014, 09:57:08 pm »
In my other question, I was asking where there is a way, using SFML , I could be able to map a 2-d array of bools onto an SFML window, or rather, is there a way I split an SFML window into a grid?

neobrain

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
Re: SFML collision detection
« Reply #8 on: November 23, 2014, 10:02:23 pm »
Collision detection is not related to graphics, its purely logical. sf::Rect has ::contains and ::intersects and sf::Sprite has ::get(Global|Local)Bounds which returns sf::Rect. The fact that you can get an sf::Rect from an sf::Sprite does not make collision detection part of graphics.

I don't think that is correct.

Using function sf::FloatRect :: intersect  you should be able to know whether the two sf::FloatRect are intersecting.

Gambit

  • Sr. Member
  • ****
  • Posts: 283
    • View Profile
Re: SFML collision detection
« Reply #9 on: November 23, 2014, 10:24:15 pm »
You dont think what is correct? sf::Rect::contains will tell you if a point is inside of it. sf::Rect::intersects will tell you if a sf::Rect is overlapping it. Read the docs.
« Last Edit: November 23, 2014, 10:28:22 pm by Gambit »

neobrain

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
Re: SFML collision detection
« Reply #10 on: November 23, 2014, 11:36:35 pm »
You dont think what is correct? sf::Rect::contains will tell you if a point is inside of it. sf::Rect::intersects will tell you if a sf::Rect is overlapping it. Read the docs.

That means you can use sf :: FloatRect :: intersects to check for collision and that effectively means collision detection in the way that I am doing it is part of SFML.


« Last Edit: November 23, 2014, 11:55:54 pm by neobrain »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: SFML collision detection
« Reply #11 on: November 24, 2014, 12:26:36 am »
is there a way I split an SFML window into a grid?
You can use a tile map.

In my other question, I was asking where there is a way, using SFML , I could be able to map a 2-d array of bools onto an SFML window
There is no reason that you can't store a 2-dimensional array (or std::vector, preferably) of bools, but what they represent is totally up to you.
std::vector<std::vector<bool>> bools;

Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

neobrain

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
Re: SFML collision detection
« Reply #12 on: November 24, 2014, 01:09:02 am »
Thanks!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: SFML collision detection
« Reply #13 on: November 24, 2014, 02:07:08 am »
Keep in mind that std::vector<bool> is a template specialization. You should read the documentation (e.g. on www.cppreference.com) before using it.

And I'd personally avoid a nested vector and use a one-dimensional vector instead; you can still map indices from 2D to 1D.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything