-2
\$\begingroup\$

I'm making a game with C++ where the program extracts the lines out of an image (via openCV), stores them in an std::vector< std::vector< int > > and the builds a tile map out of it which is used for a simple jump'n'run game (with SFML).
Having everything else implemented, I still struggle when it comes to implementing the collision detection. I have tried several approaches (i. e. the second approach on this site) but always failed. This means that the player is able to move over obstacles as there was no collision detection.
So I need a simple, fail-safe way of implementing a collision detection (or maybe just the algorithm) when using a tile map.
I don't want my code or my former approach corrected, but I'm asking for a simple way to implement a collision detection in a 2d tile-based game.

\$\endgroup\$

closed as unclear what you're asking by Anko, kevintodisco, MichaelHouse Feb 4 '14 at 15:18

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    \$\begingroup\$ "Failed" is too generic. Can tell us what is your exact problem ? collision detection is a broad topic. so unless you provide us with a specific problem, it's hard to guess. \$\endgroup\$ – concept3d Feb 1 '14 at 14:38
  • \$\begingroup\$ With failed I mean that it just does not work, the player is able to just move through the obstacles. I have pasted my latest implementation here: pastebin.com/68MSEvPP. To make it clear: All I want is a way of hinder the player to move further than the nearest obstacle in his way. \$\endgroup\$ – BlackMamba Feb 1 '14 at 14:42
  • \$\begingroup\$ Well, I understand that failed means does not work. What I meant is describing the problem in more details, like the exact behaviour. \$\endgroup\$ – concept3d Feb 1 '14 at 14:44
  • \$\begingroup\$ I want the player, when given a movement, to stop when encountering an obstacle on his way. This is done via checking for each axis which lines (on the opposite axis) the player crosses with his movement (i. e. when movement(10,3), he crosses 3 lines when checking the x axis) and then looking on each of it for obstacles (in the vector of the tilemap). When there is an obstacle, the player mustn't move further than that. In reality, the player is able to move through obstacles without being stopped. So basically it seems as the collision detection is being ignored. \$\endgroup\$ – BlackMamba Feb 1 '14 at 14:55
  • \$\begingroup\$ @BlackMamba Please update your question with the information in your comment. Have you tried drawing the lines and tests that your collision detection method is based upon? \$\endgroup\$ – kevintodisco Feb 1 '14 at 17:21
2
\$\begingroup\$

Heere are the generic steps, where are you stuck?

Alright.

  1. Create a bounding box for the character. It needs to have a center (x, y), width and height measured in the smallest game units used.
  2. Write code that checks if a bounding box intersects with a tile.
  3. When you want to move the character (lets say) to the left, check if by moving it one unit to the left, it will cause the bounding box to intersect with a solid tile. If it does, don't move it left (The same with all other directions).

How to check for intersection between rectangles?

Assuming these are the corners on the left side of your bounding box (x, y0), (x, y1) (x is the same on both).

  1. Check where they are positioned (in the tile-map 2d array) after moving one step right: ie (x+1,y0) (x+1,y1).
  2. Check in which tile they are positioned in. ie (x+1) / TILE_SIZE, y0 / TILE_SIZE same with y1 for the other corner.
  3. Iterate from the tile the upper corner is to the one the bottom corner is in. ie :

    for(i = tile_y0; i <= tile_y1; i++){
      // False means the character cannot move in that direction.
      if tile_map(tile_x, i).is_solid() return false;
      else return true; // It can keep moving
    

The same works for every direction of movement.

\$\endgroup\$
  • \$\begingroup\$ I see, but what if there are more than one movement directions per update? In my program the player may move i. e. three to the right and four down. If I check for all tiles [y0;y1] and [x0;x1] I don't check for the direction the player is moving at all. \$\endgroup\$ – BlackMamba Feb 2 '14 at 19:15
  • \$\begingroup\$ @BlackMamba If you understand how to check for moving one pixel to the right and you understand how to move one pixel down, simply do each of them once in a loop until both fail or you are done moving. \$\endgroup\$ – wolfdawn Feb 2 '14 at 20:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.