Help: Tile-based Collision Detection with Angle

Started by
3 comments, last by pek 14 years, 9 months ago
Hello everyone, I have a small problem and couldn't google a solution so here I am. I am currently creating a Jezzball clone (http://en.wikipedia.org/wiki/JezzBall or http://www.freewebarcade.com/game/jezzball/) and have a problem with collision reaction. I have a tile-based level which I store as a multidimensional array of ints. Anything greater than zero is a non-passable tile. Now, I can easily detect if the ball is out of the level and simply reverse it's trajectory. Example:

if (Location.X > GridBounds.Width)
    traj.X = -traj.X;
But what about the non-passable tiles? I have a way to calculate if the tile in the balls current position is non-passable or not, but I don't know what to do with this. I figured that I must somehow apply an "angle of reflection" type reaction with the balls and the non-passable tile. But all I found where solutions that involving surface normals. My tile-based level doesn't have such a thing. I hope I made my problem clear. Any ideas? Thank you.
Advertisement
Is the problem (1) finding the collision, or (2) handling the collision when it is found (i.e., bouncing)?

If #1, this is a circle-AABB test.

If #2, to reflect the velocity,
a - Compute the components of the velocity that are normal and tangent to the collision plane.
b - Reverse the sign on the normal component
c - Add the components back together.
Do this as vector math with dot products; no angles are necessary.
Well, it's 2.. But it is a little more complicated.

You see, there is no such thing as plane. There are only tiles. I have a ball class that holds it's location and it's trajectory (how fast in each direction does it move). I then have a method that, given a location, it will give me what int that tile is. If that int if greater than 0, it's a non-passable tile.

What I do is move the ball by the trajectory and then see if in it's current position the tile is passable. If not, I have to make it bounce of. But the problem is that I don't have anything that indicates if the ball is hitting a horizontal plane or a vertical. I just have that now it is colliding with a non-passable tile (a single point in the level).

Am I making things clear or complicating them more?

Now that I am explaining the problem I start thinking of how to solve this. I figured, after a collision with a tile has been detected, I have to find if the ball is hitting a horizontal or vertical wall. I think I will do this by searching the neighboring tiles. And probably I will do what your 2 says.

Good so far?
Quote:Original post by pekNow that I am explaining the problem I start thinking of how to solve this.
One of the best ways to solve a problem is to ask for help - not necessarily because you'll get it, but because just explaining it will make you realize the solution. :D
---------------------------------dofile('sig.lua')
Yes, well I did come up with a solution although I didn't finish it because I think it is really not a good idea.

What I started doing is checking all the surrounding tiles if they are non-passable. But slowly I realize that the code is beginning to get ugly and messy. Here is some pseudocode:

Point curr = getPointInLevel(location);

if curr.X == 0
this means that we are in the far left
if curr.X > MAX_X
this means that we are in the far right
if curr.Y == 0
this means we are at the top
if curr.Y > MAX_Y
this means we are at the bottom
if level[curr.X - 1,curr.Y] == NON_PASSABLE
&& level[curr.X + 1,curr.Y] == NON_PASSABLE
this means that it is a vertical wall

and so on so forth

I find this really really ugly and I feel that there must be a better way.

Any ideas?

This topic is closed to new replies.

Advertisement