4
\$\begingroup\$

I'm trying to make collision for a 2D game, the player (car) has to collide with the walls of the track when it hits them. I looked into pixel color detection, and X,Y -based collision (But since its a race track, which isn't square, I don't think this will be the best solution. Correct me if I'm wrong).

I understand the concept of collision for straight lines or squares, but i have no idea how to make a perfect collision in the corners of the track. example race track.

I've been searching the web a lot for tutorials and documents on this subject, but failed to find any real examples that don't use XNA or Unity. I need to find a solution that doesn't include using any kind of game engine.

Any links / documents / code snippets, or even pseudo code snippets would really help me a lot.

An example would be: Per Pixel Collision , the thing about this link is that it uses xna, which i can not use.

\$\endgroup\$
4
  • \$\begingroup\$ gamedevelopment.tutsplus.com/tutorials/… dyn4j.org/2010/01/sat \$\endgroup\$
    – jgallant
    Oct 27, 2015 at 14:35
  • \$\begingroup\$ Draw a black and alpha version of the track (just the walls) and use per-pixel collision. Per-pixel collision isn't based on XNA. It might use classes like Matrix that are automatically referenced by an XNA project but you should be able to get a reference to them via importing into a normal project. Try referencing msdn.microsoft.com/en-us/library/… \$\endgroup\$
    – Superdoggy
    Oct 27, 2015 at 15:00
  • \$\begingroup\$ That race track is made of triangles, use a triangle-point collision algorithm \$\endgroup\$
    – Bálint
    Dec 26, 2016 at 16:45
  • \$\begingroup\$ Per pixel collision is too expensive. I would recommend you to avoid this technique, and use bounding box collisions. If you want more information about bounding box collisions i need to know if you want them to have rotations or not. \$\endgroup\$
    – Haruko
    Dec 26, 2016 at 17:09

3 Answers 3

1
\$\begingroup\$

Since you don't want XNA code snippets, some pseudo code then. I assume you have you're able to read the bitmap or sections from the bitmap since you're referring to the collision part only. Also this varies from the engine/technique used.

For per pixel collision, you would do this:

Get the source rectangle you want to check (the car) and the target rectangle (the track section underneath your car). Collect the pixels from the bitmaps corresponding these rectangles.

Let's say this is the car bitmap where X is a colored pixel:

...xx...
x..xx..x
xxxxxxxx
x..xx..x
...xx...
x..xx..x
xxxxxxxx
x.xxxx.x

The tracksection would be of equal size, since we only check against the part of the bitmap that is underneath the sprite (let's say it is part of a curve):

........
........
........
......xx
...xxxxx
.xxxxxxx
xxxxxxxx
xxxxxxxx

Now you check each pixel in the car rectangle against the pixel at the same location in the track rectangle. There are a few options here: 1. If all car x pixels are on a track x pixel, the car is entirely on the track. 2. If at least 1 car x pixel is matched against a track . pixel a part of the car is not on the track, and a collision against the scenary occurs. 3. If no car x pixel matches against a track x pixel, the car is completely off the track.

Usually as soon as a car x is matched against a track ., the algorithm stops and returns a collision (condition 2 is met), but you can vary this to suit your game mechanics.

Another option is to describe the track using polygons, this would enable you to do simpeler collision checks however it may be a bit harder to create elaborate irregular tracks.

\$\endgroup\$
1
\$\begingroup\$

Here is how I would do it:

When creating the map, I'd make lines going from start to finish (probably looping). The lines on the outside (towards the edges of the map) would be clockwise, and the lines on the inside (pointing towards the center of the map) would be counter clockwise.

While the car is racing, check the collision of the closest lines. It's up to you how to do this, you can for example divine the stage in cells, and check only lines inside the car's cell. Then use this formula:

d=(x−x1)(y2−y1)−(y−y1)(x2−x1)

This detects if a point is on the left or right of a line. x, y are the point's position, x1, y1 and x2, y2 are the line's edges. if d is positive, the point lies on one side of the line, while if it is negative it lies on the other side.

To check if a car is colliding with the edges, check the outer line with this formula, if d is positive, the point is inside the track (on the right side of the line, assuming it's facing from x1, y1 to x2, y2. Check the same with the inner line. if d is positive again, point is inside the track.

If a line shows d as negative, then the car has just collided with that line.

Obviously a car is not just a point, but a full mesh/sprite, in this case you can apply the formula multiple times on the car's corners, this way you can not only tell if the car has collided or not, but also which side collided, so you can handle it differently.

Here's an example of what I mean:

enter image description here

\$\endgroup\$
1
  • \$\begingroup\$ You will likely to need to check the segments before and after the closest one as well to avoid errors at the segment end. \$\endgroup\$ Oct 22, 2018 at 11:34
0
\$\begingroup\$

Even if you don't use XNA or Unity, you could still use a C# physics engine, for instance VelcroPhysics (formerly Farseer Physics, a port of Box2D with additional features)

You could also code your own physics from scratch, but I wouldn't recommend it unless you have a really good reason to do so. I did it on a project as I wanted some specific behaviour on some collisions, but it's a lot of work and it means you have to debug and maintain it as your game evolves...

If you still want to follow this path, you should consider your car and the track as shapes (a rectangle for the car and segment list for both sides of the road). Then, knowing the position of your car at the previous frame and its new position after update, you can check whether the rectangle has crossed any segments. In my case, instead on segments, I decomposed my word in angles (acute or obtuse) which where easier to test against my character's rectangle.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .