2d collision detection with tiles
I am having trouble figuring out collision detection in a SubSpace clone I'm working on. I've read dozens of tutorials on collision detection and many many examples and I still can't quite get it. What I have now is a model using 16 points around the ship that are checked for being in a solid tile. The game checks 8 points in each direction (example the 8 points on the south side and 8 points on the east side if the X and Y velocity are positive) the problem is that in every instance of collision, both velocities are flipped meaning when I hit a wall horizontally the X and the Y velocity are negated when only the X should be. I would be eternally grateful for any assistance.
The 16 collision points are drawn here so I can visualize what I'm working with, also SDL seems to draw rotated images with 0 starting at the top and angle increasing clockwise. I'm using trig circle with 0 being east and angle increasing counter-clockwise, if it matters. The ship is 32x32 and tiles are 16x16.
This picture illustrates which tiles are being checked for collision.
edited to show images
Typically you wouldn't perform collision detection of this sort using individual points (as you appear to be doing); rather, you would represent the objects using solid shapes (circles, boxes, etc.). As for 'bouncing', that is usually achieved by reflecting the velocity vector with respect to the normal of the surface with which the object has collided.
Here is a tutorial that is often recommended and might be relevant here. If you've already read it, you might give it another look, as the methods it describes are generally more robust and accurate than the point-sampling method you're using currently.
Another option would be to use an existing physics engine, such as Box2D.
Here is a tutorial that is often recommended and might be relevant here. If you've already read it, you might give it another look, as the methods it describes are generally more robust and accurate than the point-sampling method you're using currently.
Another option would be to use an existing physics engine, such as Box2D.
You culd also use very dummy system. Make grid and check whether the ship on certain position colide. Position in grid is easy and fast to calculate.
If you want only cubes, than you should be fine with bool grid. If you want triagles, as i see, you could use byte grid. 0 = space (ship can move there); 1 = solid wall blcok (no move at all); 2 = triangle typ #1; 3 = triangle type #2 etc.
And for triangles you can use for example:
for other value, than one, you can use lists of those triangles and than fast iterate through all of them and calculate whether the point is inside the triangle or not (very easy test).
Calculation position of ship in grid is also trivial. Take "center" of your ship (or one of ship cubes, as I see on picture #2), calculate its position in grid and other parts are only + / - 1 in several direction. Than you get positions (indexes) of the ship.
At the end you take every ship index and make if test with grid.
At the end, you don´t need SAT and nothing like this for walls. I recomend SAT tests for enemies or some movable objects (bonuses).
I use bool grid for walls and it works perfect :-)
If you want only cubes, than you should be fine with bool grid. If you want triagles, as i see, you could use byte grid. 0 = space (ship can move there); 1 = solid wall blcok (no move at all); 2 = triangle typ #1; 3 = triangle type #2 etc.
And for triangles you can use for example:
for other value, than one, you can use lists of those triangles and than fast iterate through all of them and calculate whether the point is inside the triangle or not (very easy test).
Calculation position of ship in grid is also trivial. Take "center" of your ship (or one of ship cubes, as I see on picture #2), calculate its position in grid and other parts are only + / - 1 in several direction. Than you get positions (indexes) of the ship.
At the end you take every ship index and make if test with grid.
At the end, you don´t need SAT and nothing like this for walls. I recomend SAT tests for enemies or some movable objects (bonuses).
I use bool grid for walls and it works perfect :-)
The way I have figured it out to work is checking the ship as a circle against all tiles in the map (later I will change it to check against all tiles nearby to be less intense on the processor.) From finding which tile specifically it collided with I take the position of the tile and the position of the ship to find whether the collision was on a horizontal or vertical edge. This needs some polishing but I believe it is the way to go. I feel stupid for not realizing how easy this was to do at first. When I implement triangles I'll need to know if it hits on the horizontal or vertical edge (outsides of the tile) or the diagonal edge (inside part of the tile.) That doesn't seem so hard now that I know how exactly to do this.
1) Average the vectors of those points that did not collide.
2) Shuffle the ship along the direction of that average vector until it doesn't collide at all.
3) Adjust the velocity to match the real movement.
2) Shuffle the ship along the direction of that average vector until it doesn't collide at all.
3) Adjust the velocity to match the real movement.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement