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

Author Topic: [Help] Making a Race Track delimited by linestrips Vertex Arrays (Collision)  (Read 3610 times)

0 Members and 2 Guests are viewing this topic.

TioMOG

  • Newbie
  • *
  • Posts: 5
  • Panthomime
    • View Profile
Well, hello guys! My first post, here :P

So, I'm doing a racing game for a college project and I'm planning on do a Isometric race track.

The problem is, when the track is created, I don't want to my car to walk on it's borders like Jesus or something like this, so I was thinking if it's possible to make a collision check with sf::VertexArrays?

Because I already have the tracks on the game (I did it like a tilemap), but it's impossible to make a tilemap collision, once the tiles are big, isometric and cover the ground and the border of the track. I saw the "getBounds()" method on the class, but I don't know what it returns in case of linestrip.

So, I would apreciate if you guys could help me to do a border with linestrip or give me better ways of doing this issue with another class/fuction, like ConvexShape or whatever :)

For a better explanation, I attached 2 files:
The first one it's the map as it is (Don't complain about it's quality, I know it's lame, but I'll improve it :P)
The second one it's the map, divided by it's tiles and with a YELLOW LINESTRIP, that could represent my idea of "Borders" that the car can't trespass;

Obs: Sorry about the bad english, it is not my native language
Obs: I have a car SpriteSheet example, if you guys need it :)
nah

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Well, hello guys! My first post, here :P
Welcome!

Quote
So, I'm doing a racing game for a college project and I'm planning on do a Isometric race track.

The problem is, when the track is created, I don't want to my car to walk on it's borders like Jesus or something like this, so I was thinking if it's possible to make a collision check with sf::VertexArrays?
Collision checks are always possible if you can precisely define a collision. SFML doesn't have any built-in support for arbitrary shapes (since you usually have to make assumptions about the shape to write a sane algorithm), but there are plenty of other resources out there.  If you want to write a collision detection algorithm yourself for your custom shapes, the thing to Google is the "Separating Axis Theorem."

https://github.com/SFML/SFML/wiki/Source:-Simple-Collision-Detection-for-SFML-2 contains a generic example of a (non-axis-aligned) bounding box test using that theorem on arbitrary sf::Sprites (ie, rotated rectangles).  Might be a good place to start.

Quote
Because I already have the tracks on the game (I did it like a tilemap), but it's impossible to make a tilemap collision, once the tiles are big, isometric and cover the ground and the border of the track. I saw the "getBounds()" method on the class, but I don't know what it returns in case of linestrip.
For getBounds(), are you talking about sf::VertexArray::getBounds()? If so, the documentation tells you what it returns:
Quote
Compute the bounding rectangle of the vertex array.

This function returns the axis-aligned rectangle that contains all the vertices of the array.
Is this not clear enough?
« Last Edit: October 19, 2014, 11:40:56 pm by Ixrec »

TioMOG

  • Newbie
  • *
  • Posts: 5
  • Panthomime
    • View Profile
Yeah, I was talking about the sf::VertexArray method.

But if the primitive it's a Linestrip, what would be the height of that rectangle?
Since it's a straight line, it would be a widthx1 px rectangle?

Ps: I will look this example. Seems pretty nice
nah

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
But if the primitive it's a Linestrip, what would be the height of that rectangle?
Since it's a straight line, it would be a widthx1 px rectangle?

Because it's an axis-aligned bounding box, the height is going to be the largest difference of y values that exists between any two points in the vertex array.  Whether it's a line strip or triangle fan or whatever has absolutely no bearing on that.  Likewise, the width will be the largest difference of x values.  Since this calculation is trivial, you can easily read the implementation yourself if you have any further questions about it: https://github.com/SFML/SFML/blob/master/src/SFML/Graphics/VertexArray.cpp#L107

For a non-axis-aligned/properly rotated bounding box, I would say the question is confused because we're still talking about geometric shapes, not rasterized pixel-based images.  A FloatRect knows nothing about "pixels".  I would therefore assume the only sensible rotated bounding box for a single line would be one that's identical to the line, with exactly zero width (unless the "line" is itself a rectangle of non-zero width).

If you're concerned is that entities will fail to collide with a shape of zero width, then yes you are correct, but it's still entirely possible to slip through a "1 pixel" rectangle if they're moving fast enough (and maybe they aren't, I don't know).  In this particular case, what you probably want to do is write your collision code not to detect collisions with the barrier itself, but rather detect any entity that has gone beyond the barrier, or perhaps detect collisions with the areas enclosed by the barriers.

P.S. In the general case this is deceptively tricky since any variations in the framerate can change what size objects do and don't collide.  This is the problem that fixed timesteps solve.
« Last Edit: October 20, 2014, 01:12:54 am by Ixrec »

TioMOG

  • Newbie
  • *
  • Posts: 5
  • Panthomime
    • View Profile
If you're concerned is that entities will fail to collide with a shape of zero width, then yes you are correct, but it's still entirely possible to slip through a "1 pixel" rectangle if they're moving fast enough (and maybe they aren't, I don't know).  In this particular case, what you probably want to do is write your collision code not to detect collisions with the barrier itself, but rather detect any entity that has gone beyond the barrier, or perhaps detect collisions with the areas enclosed by the barriers.

P.S. In the general case this is deceptively tricky since any variations in the framerate can change what size objects do and don't collide.  This is the problem that fixed timesteps solve.

I am studying the possibility of doing a area for colision from a certain distance before the track borders. Since I'm dealing my cars as bounding boxes (they're close to the box format), I could make this so the car still can touches the border (not a big concern at the moment, actually).
For a superficial look, Simple Collision Detection for SFML 2 could be a solution to this case, once I could make a rectangle and rotate it 30ยบ so it aligns with the limits that I want and work as a linestrip.

Just for the record, I'm not looking for a perfect collision system, I just don't want my cars to trespass the race circuit. My game is basically a remake of Rock 'n Roll Racing with some little improvements.

There's some others approuchs you could recommend for me to see what's better fits in my needs?
nah