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

Author Topic: What's the best approach for collision in a vertex array tilemap?  (Read 6340 times)

0 Members and 1 Guest are viewing this topic.

The Terminator

  • Full Member
  • ***
  • Posts: 224
  • Windows and Mac C++ Developer
    • View Profile
Hi there,

I've utilized the vertex array tilemap, but I'm having issues with collision. My current system is really hit and miss and often doesn't work at all, and it depends on checking for bounding-box intersection between the tiles (in the form of FloatRects). Is there a better way to more accurately measure collision?

Thanks
Current Projects:
Technoport

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: What's the best approach for collision in a vertex array tilemap?
« Reply #1 on: April 27, 2014, 05:26:31 am »
More than likely there is something wrong with your code. That is why you should always post a complete and minimal example.
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

The Terminator

  • Full Member
  • ***
  • Posts: 224
  • Windows and Mac C++ Developer
    • View Profile
Re: What's the best approach for collision in a vertex array tilemap?
« Reply #2 on: April 27, 2014, 05:40:16 am »
Here's the methods where I check if the next position requested by the user is feasible. I was just trying to get it working so please excuse the dirty code:

bool SPlayer::nextPosValid(const sf::Vector2f& offset)
    {
        sf::Vector2f offsettedPos(m_sprite.getPosition().x + offset.x, m_sprite.getPosition().y + offset.y);

        //The bounding rectangle of the future player
        sf::FloatRect rect(offsettedPos,
                           sf::Vector2f(m_sprite.getGlobalBounds().width, m_sprite.getGlobalBounds().height));

        if (SSceneManager::getWorld().getCurrentCell()->getTileMap().check(offsettedPos, 2))
        {
            Ataxia::TileMap::Tile tempTile = SSceneManager::getWorld().getCurrentCell()->getTileMap().check2(rect, 2);

            if (rect.intersects(tempTile.bounds))
                return false;
        }

        return true;
    }

bool check(const sf::Vector2f& pos, int tileType)
        {
            for (auto& iter : m_tiles)
            {
                if (iter.tileType == tileType)
                {
                    if (iter.bounds.contains(pos))
                        return true;
                }
            }

            return false;
        }

        Tile& check2(const sf::FloatRect& rect, int tileType)
        {
            for (auto& iter : m_tiles)
            {
                if (iter.tileType == tileType)
                {
                    if (iter.bounds.intersects(rect))
                        return iter;
                }
            }
        }

Thanks!
Current Projects:
Technoport

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: What's the best approach for collision in a vertex array tilemap?
« Reply #3 on: April 27, 2014, 05:52:20 am »
Checking a single point before checking the actual bounding box isn't going to get you very far.  ;)
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

The Terminator

  • Full Member
  • ***
  • Posts: 224
  • Windows and Mac C++ Developer
    • View Profile
What's the best approach for collision in a vertex array tilemap?
« Reply #4 on: April 27, 2014, 01:50:06 pm »
Oh I see. So when checking if the player's position is contained within a tile, check all the four vertices of the square?
Current Projects:
Technoport

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: What's the best approach for collision in a vertex array tilemap?
« Reply #5 on: April 27, 2014, 01:58:13 pm »
Really you should combine those checks, and check the bounding box for intersection (like check2) and return true/false. Having multiple checks when just dealing with rectangles is redundant.
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

The Terminator

  • Full Member
  • ***
  • Posts: 224
  • Windows and Mac C++ Developer
    • View Profile
Re: What's the best approach for collision in a vertex array tilemap?
« Reply #6 on: April 27, 2014, 03:48:05 pm »
Would I have to create four FloatRects? One for each vertice?
Current Projects:
Technoport

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: What's the best approach for collision in a vertex array tilemap?
« Reply #7 on: April 27, 2014, 03:51:50 pm »
All you need to do is use intersects() on the bounding box of the player and the bounding box of the tile.  You don't need to do any additional checks before or after (assuming you just want to know whether he's in the tile or not).
« Last Edit: April 27, 2014, 03:53:28 pm by Ixrec »

The Terminator

  • Full Member
  • ***
  • Posts: 224
  • Windows and Mac C++ Developer
    • View Profile
What's the best approach for collision in a vertex array tilemap?
« Reply #8 on: April 27, 2014, 05:26:09 pm »
I did exactly that, but it was not accurate and often didn't work. I'm not using a sprite for the tiles, since it's a vertex array tilemap.
Current Projects:
Technoport

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: What's the best approach for collision in a vertex array tilemap?
« Reply #9 on: April 27, 2014, 05:32:48 pm »
Doesn't matter that you are vertex arrays, either way you need to get a bounding box for each tile.
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

G.

  • Hero Member
  • *****
  • Posts: 1593
    • View Profile
Re: What's the best approach for collision in a vertex array tilemap?
« Reply #10 on: April 27, 2014, 05:37:39 pm »
I'm not sure I understand, it doesn't matter if you're using sprites or a vertex array.

If your tile is an axis aligned rectangle made of 4 vertices you can easily create an sf::FloatRect(x, y, w, h) from these.
x and y are the coordinates of the top left vertex of the tile. w is the difference between the abscissa of one of the vertices on the right side of the tile and the abscissa of one of the vertices on the left side of the tile. h is the difference between the ordinate of one of the vertices on the bottom side of the tile and the ordinate of one of the vertices on the top side of the tile.

Same thing for the bounding box of your player (or if it's a sprite you can retrieve it with getGlobalBound).

The Terminator

  • Full Member
  • ***
  • Posts: 224
  • Windows and Mac C++ Developer
    • View Profile
Re: What's the best approach for collision in a vertex array tilemap?
« Reply #11 on: April 27, 2014, 07:38:18 pm »
Got it working. Thanks a lot for the detailed explanation G, I was just confused on how to exactly construct the tile's FloatRect, but you cleared that up.

Thanks again!
Current Projects:
Technoport