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

Author Topic: Help with Tile collisions  (Read 17752 times)

0 Members and 2 Guests are viewing this topic.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Help with Tile collisions
« Reply #15 on: February 08, 2014, 05:26:38 am »
First, you could use sf::Vector2f for tileSize so it uses float, or you could cast the integers to float to force it to comply.
Second, I don't know why you need a function to work out the size of each tile; it will be in the line that created the tilemap.
This is from the tutorial where you got the tilemap class (this is the code that loads the map):
TileMap map;
    if (!map.load("tileset.png", sf::Vector2u(32, 32), level, 16, 8))
        return -1;
The size of each tile is here in the sf::Vector2u - they're 32 x 32. Which values you used there in that line is the size of your tiles.

The tile size is used to find which tile the sprite is in by using the sprite's position using something like what I posted earlier.

Just to clarify, where is your tilemap? Is it in the top-left corner of your window? Does it fit into the window?
« Last Edit: February 08, 2014, 05:28:47 am by Golden Eagle »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

gop_t3r

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Help with Tile collisions
« Reply #16 on: February 08, 2014, 06:06:57 am »
You lost me now; where am I supposed to be implementing this? I'm assuming it's in the class implementation file, hence I created a function. My tilemap is actually stored in a file, and I modified my tile loader function to read from it. My tileset is actually 40 x 40; and yes, the origin is in the top-left corner of the window, and it does fit into the window as well.

I think some code could help out here, please; doesn't have to be accurate but I need an idea as to what you're getting at. If it's in main.cpp, then I'm happy to comply. In which case, there should be something like this:

float result = (player.sprite.getPosition().x - map.getPosition().x) / 40;
 

So far so good.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Help with Tile collisions
« Reply #17 on: February 08, 2014, 05:22:16 pm »
Since you're map is at (0, 0) - the top-left - it's not necessary to subtract its position from the sprite's.

Please take some time to study this image. I hope you understand it because it's the clearest representation of what I'm trying to explain.


tiles[tileNumber] would then tell you which tile (from your array of tiles) is in under the sprite at its origin. You would then need to decide what to do with that information e.g. Is player in a tile that it can pass through, is the next tile in the direction that the player is moving a tile that the player can pass through.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Help with Tile collisions
« Reply #18 on: February 08, 2014, 09:29:37 pm »
You just need to decide which tiles should collide and which ones shouldn't. Then test for those values.

For example, if the player shouldn't collide with tiles 0 or 1 but should collide with 2 or 3, then it would be:
if ((map.pTiles[tileNo] == 2) || (map.pTiles[tileNo] == 3))
{
  // player has collided with something it shouldn't have so move/stop/alter player accordingly.
}
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

gop_t3r

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Help with Tile collisions
« Reply #19 on: February 09, 2014, 12:08:56 am »
You just need to decide which tiles should collide and which ones shouldn't. Then test for those values.

For example, if the player shouldn't collide with tiles 0 or 1 but should collide with 2 or 3, then it would be:
if ((map.pTiles[tileNo] == 2) || (map.pTiles[tileNo] == 3))
{
  // player has collided with something it shouldn't have so move/stop/alter player accordingly.
}

Thanks, the collision test works! What I'm planning to do is simply have platforms 2 and 3 solid, such that the player can't move through them. How can I prevent a player from moving 'through' tiles? I tried a premature method of just subtracting 40 from the position thereof, but it doesn't do what I really want.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Help with Tile collisions
« Reply #20 on: February 09, 2014, 01:17:40 am »
Ah good! :)
Well, you now know how to compare tiles in the map with the pixel positions (e.g. sprite origins). What you do with that information, however, is up you. I can't write your code for you :p You should google some tips for dealing with collisions.

FYI, "it's not doing what I want" doesn't give enough information for anyone to help; (most) people aren't mind-readers ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

gop_t3r

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Help with Tile collisions
« Reply #21 on: February 09, 2014, 05:35:55 am »
At least I have tile-collisions, what happens as a result thereof varies; indeed this thread's purpose has thus been satisfied and I hereby declare this issue resolved.

Thanks for your help!
« Last Edit: February 10, 2014, 04:06:45 pm by gop_t3r »

gop_t3r

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: [SOLVED] Help with Tile collisions
« Reply #22 on: February 10, 2014, 04:13:28 pm »
Hi, I am reopening this thread as an issue has arisen which I have not noticed until today:

The tile collision works, but appears the program thinks there's a collision when I am on the same x-axis as the specified tiles. Say a player collides with a tile at (400, 300), it returns true (there is a collision), but if I move along the x-axis outside the tile to somewhere like (300, 300), it still returns true and thinks that it's on the same tile as the player was on (400, 300).
« Last Edit: February 11, 2014, 07:53:02 pm by gop_t3r »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: [SOLVED] Help with Tile collisions
« Reply #23 on: February 10, 2014, 05:51:01 pm »
it still returns true and thinks that it's on the same tile as the player was on (400, 300).
How do you know it thinks that? How are you testing to see if it's still true?

I'm using the same information you have given me regarding this collision.
The information I gave you was to detect which tile the origin of the sprite was in (so you could work out whether it was supposed to collide or not). For the actual collision detection, you would need to test the boundary boxes for the sprite against the tiles' boundary boxes.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

gop_t3r

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: [SOLVED] Help with Tile collisions
« Reply #24 on: February 10, 2014, 06:48:53 pm »
it still returns true and thinks that it's on the same tile as the player was on (400, 300).
How do you know it thinks that? How are you testing to see if it's still true?

I'm using the same information you have given me regarding this collision.
The information I gave you was to detect which tile the origin of the sprite was in (so you could work out whether it was supposed to collide or not). For the actual collision detection, you would need to test the boundary boxes for the sprite against the tiles' boundary boxes.

The only way for it to return true is through the if statement provided; I have run the program and even though the player is not at the tile BUT is on the same horizontal axis as the tile, it returns true.

This is what I've concluded from testing, using the coordinates of the player:

Test 1: Where x = 168, y = 228 --> NO collision;
Test 2: Where x = 100, y = 332 --> collision; (this co-ordinate is located to the LEFT of the tile, outside thereof)
Test 3: Where x = 374, y = 320 --> collision; (this co-ordinate is located within the tile)
Test  4: Where x = 740, y = 308 --> collision; (this co-ordinate is located to the RIGHT of the tile, outside thereof)

As you can see, the outlier y value concludes that there is something wrong with the y value in collision detection. I have used the information you gave me to work out which tile the sprite was in, but what's interesting is that in all those three collision detections, REGARDLESS of what's being shown on screen; the tileNumber returns 2. In collision tests 2, 3 and 4: tileNumber returns 2, even though in collision tests 2 and 4 were OUTSIDE the tile. I don't think this is a problem with the actual collisions detection, but rather in how the program is interpreting which tile is which. So far, it only happens to tile numbers 2 and 3 and a collision test on both tiles returns true regardless of where we are on the horizontal axis.

I think a problem lies in this line of code:

float tileNo = (gridPosition.y * gridSize.x) + gridPosition.x;
 

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Help with Tile collisions
« Reply #25 on: February 10, 2014, 07:17:52 pm »
Do you only have one tile that would be tested for collision? Could it be "colliding" with a different tile that should be collided with?

That code is fine as long as your tile data is an array which goes through each x before y (i.e. like the tutorial tilemap does). It also relies on the fact that your tile map is located at the top-right corner, the tile size you use to calculate the grid sizes is correct, and the grid size is correct.

How are you testing this? Are you placing a sprite in one place explicitly, running the code, checking to see if text is output, and then ending the code. Or, are you moving the sprite without closing the program?
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

gop_t3r

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Help with Tile collisions
« Reply #26 on: February 10, 2014, 07:39:58 pm »
Do you only have one tile that would be tested for collision? Could it be "colliding" with a different tile that should be collided with?

That code is fine as long as your tile data is an array which goes through each x before y (i.e. like the tutorial tilemap does). It also relies on the fact that your tile map is located at the top-right corner, the tile size you use to calculate the grid sizes is correct, and the grid size is correct.

How are you testing this? Are you placing a sprite in one place explicitly, running the code, checking to see if text is output, and then ending the code. Or, are you moving the sprite without closing the program?

My tile-map is located at the top-left hand corner. I am testing this program by having my player moving without closing the program. If it moves to the aforementioned coordinates, the results thereof appear.
« Last Edit: February 11, 2014, 07:53:28 pm by gop_t3r »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Help with Tile collisions
« Reply #27 on: February 10, 2014, 09:00:53 pm »
My tile-map is located at the top-left hand corner.
Yeah, I meant top-left :p

The problem is that the computer thinks the tiles are drawn as they appear on the first image.
I'm not sure how you know what your computer is thinking.

I am testing the collision through a simple cout << "collision" << endl; because I need to ensure that a collision is actually happening.
This is the most interesting part. Do you mean that you output "collision" to the console when there is a collision based on whether or not the sprite is in the tile at that time?
If so, what console readout do you get? Is it just one output that stays there?

Also, at the place where it isn't supposed to collide... Does it show collision if you go there without going to the other place first?
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

gop_t3r

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Help with Tile collisions
« Reply #28 on: February 10, 2014, 09:42:52 pm »
The collision check only couts "collision" if and only if a collision has occurred, which should return true WHEN the tile 2 is collided with. The interesting part is this: look back at tests 1-4 in my other post and follow this:

Do you not see? The computer thinks the tiles that are meant to be 0, are in fact 2. By the way, when I say 'think', it is euphemism for whatever the computer assumes to be right or wrong. (I know the computer doesn't think)

What's funny is that even if I'm not at tile 2, it still returns true for collision IF I AM ON THE SAME HORIZONTAL AXIS as tile 2 or any other tile I want to collide with. So long as I am colliding with the tile, then it will continue to cout << "collision" until I leave the vicinity. Have you tested the code to see if you can detect the issue?
« Last Edit: February 11, 2014, 07:53:40 pm by gop_t3r »

gop_t3r

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Help with Tile collisions
« Reply #29 on: February 10, 2014, 10:18:54 pm »
I've just implemented a bounding box collision test from another class I use for it; it appears the issue hasn't been resolved and am convinced that this has definitely something to do with the way tileNo is calculated. Just out of curiosity, what data type do you expect from pTiles or tileNumber? You haven't defined any data types in your example, and I'd like your input as to which data types you expect. Just so you know, pTiles is a vector array of integers.