#21327 - DigitalChaos - Thu May 27, 2004 10:21 pm
Right now I'm making a little racing game just to get comfortable and used to GBA programming. I made a decent pong game through a tutorial, so I understand collision detection for the edges of the screen and the bars. But for a track, it bends and curves, how do you do collision detection on the edges of the tracks?
Also, anyone know a link where I can get some sprites, I can't make decent sprites.
Thanks.
#21328 - Miked0801 - Thu May 27, 2004 10:37 pm
For curves, there are a couple of ways that come to mind.
1. Create a bunch of small line segments and collision detect with each within a close radius of the object - probably how I would do it.
2. If the curve is a true circle, define a center, radius, and start/end angle for it and do a radius check against the sector that the wall represents. A very fast check against true circle curves. Confusing so here's an example.
You have a curved wall that a radius 10 pixel circle would fit. Place the center of that circle so that the edge of the circle would overlap the wall. Let's say that it's a hairpin corner so that the wall starts at 270 degrees (bottom of circle) and continues counter-clockwise through 90 degrees (top of circle). To collide check, setup a collision box around the half circle and check for inclusion. If within, do a radius check against the circle. If out of the radius or exactly euqal, you just hit the wall. Pretty quick for large walls areas, but not as efficient on smaller circle sectors.
#21333 - DigitalChaos - Thu May 27, 2004 11:18 pm
none of the curves would be a true circle. It would just be bends in the road. How would you create a bunch of line segments? I'm not sure i'm understanding this. Could you please expand on this idea.
#21334 - bats - Thu May 27, 2004 11:42 pm
It shouldn't be too difficult to create line segments. The concept is like in calculus: a smooth curve can be simulated by a series of line segments, and the accuracy of the match improves when the line segments are shorter.
Miked is suggesting that when your object is moving around the map, check it against all line segments within a certain radius; say, a little larger than the size of your object. This way, you're not doing the check against all of the segments. It seems like it might be difficult to do the circle/line segment check unless the segments are small, though. I'd probably divide the map into sectors and only check against segments in my current sector, and leave the segments relatively large.
The difficult part will be detecting collision between your bounding box and the line segment (unless you're up on your math); so just find some code that does it.
Ben
#21336 - keldon - Fri May 28, 2004 1:11 am
collision detection is dirt easy.
Remember that old maths question, two trains travelling at x mph from y metres, how long does it take .. that is collision detection in its best form. But you don't need to worry about that, I just thought I'd make you aware of real collision detection so that you don't get trapped on the way.
I am assuming that this a micro machines style racer. Then don't work with curves yet, not even the professionals did so in the early days, so you need not bother - - simple diagonals will do, even then you could use simple square tiles, but here is how you do it with basic diagonals.
Now I would tackle this with a larger map, which is grid detection. Now if you're on an empty grid, then there is no collision. Now if it is an occupied grid, it can be of two types, partly filled or filled. A partly filled one would be something such as a diagonal line.
It may help to draw out a square with (0,0) on the top left corner, (9, 0) on the top right, (0,9 ) on the bottom left and (9,9) on the bottom right
Consider this square with (0,0) being the top left, and (9,9) being the bottom right. And this square is half filled on the top left, and the bottom right is not. Then (x,y) where x + y >= 10 there is not a collision.
If the bottom left is free, and the top right is occupied then (x,y) where y-x>=0 there is no collision.
The other corners are the same, just with x+y < 10 and y-x> 0.
Maybe this answer was a little too mathematic as I don't even know your age and abilities, but I hope you understand this simple method of detecting collision without having to render a grid and check 10*20 positions on it to check for collision.
#21337 - keldon - Fri May 28, 2004 1:19 am
I felt it should be on a seperate post so that it doesn't seem too long to read since they are seperate. Bats is right, you do need to understand maths to do collision detection. I assume you have at least done those maths exercises where you have to calculate where two lines cross. That is how collision detection works. If you have for example two objects travelling at different speeds from two different positions, they will either collide or not. If the objects have different gradients then they will definately collide, or if they are on the same position with the same gradient; otherwise they will not.
But line detection is only ever widely used in the 3rd perspective, but I think people should be aware of how it works. This isn't the best place to write a tutorial on it, so I've just introduced you to the small topic. But I urge you to keep it simple in this stage, besides I'm still unsure what type of racing game you're developing.
#21344 - DigitalChaos - Fri May 28, 2004 2:44 am
Thanks for the replies. The game is nothing big. It's a top down view racer, where you are looking down at the car. I'm 18 and I know my math. Never taken calculus tho, only up to Algebra 2 and Geometry.
#21348 - dagamer34 - Fri May 28, 2004 3:12 am
If it's top-down, then you could create a collision map for the road and go from there.
_________________
Little kids and Playstation 2's don't mix. :(
#21353 - DigitalChaos - Fri May 28, 2004 3:39 am
yeah, i don't know how to do that though :(
#21357 - tepples - Fri May 28, 2004 4:04 am
In, say, Mario Kart, road tiles can be "road" or "grass" or "wall". If the player is on a "road" tile, use "road" physics; likewise for "grass". If the player attempts to enter a "wall", move the player to the edge of the tile and bounce the player's velocity.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#21358 - DigitalChaos - Fri May 28, 2004 4:08 am
tepples,
that is good. how do i go about putting certain characteristics onto a certain tile? How would i do that in the code, thanks for all the help guys.
#21362 - dagamer34 - Fri May 28, 2004 4:24 am
tepples wrote: |
In, say, Mario Kart, road tiles can be "road" or "grass" or "wall". If the player is on a "road" tile, use "road" physics; likewise for "grass". If the player attempts to enter a "wall", move the player to the edge of the tile and bounce the player's velocity. |
I was thinking a little bit further. You could have some tiles that are 1/2 road and 1/2 grass with a diagon split. Something like this
Code: |
------
|//// |
|/// |
|// |
|/ |
------
|
It's supposed to be a tile, but that's not the point. If the grass was the white area, and the road the '/' area, and the split is at 45 degrees, you could use some math to create more interesting shapes and more intersting collisions.
_________________
Little kids and Playstation 2's don't mix. :(
Last edited by dagamer34 on Fri May 28, 2004 4:41 am; edited 2 times in total
#21363 - DigitalChaos - Fri May 28, 2004 4:34 am
I understand what you guys are saying, i am unsure how to implement the code. how to give each tile characteristics and set up the collision detection.
#21364 - sajiimori - Fri May 28, 2004 4:46 am
Make an array that's the size of your map, where each element has a number that represents the terrain type. When objects cross a tile border, check the terrain type of the tiles it's crossing into and respond as you see fit.
If your objects are moving faster than 1 tile per frame, it's more complicated because you might jump over something solid. Start simple for now and only have slow-moving objects.
#21365 - Miked0801 - Fri May 28, 2004 5:09 am
As Sajimori says. Create a 2Dim array that holds the collision info for the map. Check for which tile you are in. If collide tile, then collide. Hell the code is easy enough so here:
Code: |
#define MAP_TILE_SIZE 8
#define MAP_X_SIZE 5
#define MAP_Y_SIZE 5
#define MAP_SIZE ((MAP_X_SIZE) * (MAP_Y_SIZE))
#define TILE_CLEAR 0
#define TILE_COLLIDE 1
const int collideMap[MAP_Y_SIZE][MAP_X_SIZE] =
{
{ TILE_COLLIDE, TILE_COLLIDE, TILE_COLLIDE, TILE_COLLIDE, TILE_COLLIDE},
{ TILE_COLLIDE, TILE_CLEAR, TILE_CLEAR, TILE_CLEAR, TILE_COLLIDE},
{ TILE_COLLIDE, TILE_CLEAR, TILE_COLLIDE, TILE_CLEAR, TILE_COLLIDE},
{ TILE_COLLIDE, TILE_CLEAR, TILE_CLEAR, TILE_CCLEAR, TILE_COLLIDE},
{ TILE_COLLIDE, TILE_COLLIDE, TILE_COLLIDE, TILE_COLLIDE, TILE_COLLIDE},
};
// This map looks like this where # is a wall and + is the road
// #####
// #+++#
// #+#+#
// #+++#
// #####
// So a simple square course.
// Returns collision type (TILE_CLEAR or TILE_COLLIDE) depending on position.
int collideCheck(int xPos, int yPos)
{
int tileXPos, tileYPos;
ASSERT(xPos < (MAP_X_SIZE * MAP_TILE_SIZE));
ASSERT(yPos < (MAP_Y_SIZE * MAP_TILE_SIZE));
tileXPos /= MAP_TILE_SIZE;
tileYPos /= MAP_TILE_SIZE;
return (collideMap[tileYPos][tileXPos]);
}
|
Untested, but should be really close if not completely correct.
#21370 - DigitalChaos - Fri May 28, 2004 6:00 am
Miked,
Thank you. I always understand much better seeing the actual code than I understand an explanation. I have never run across ASSERT(). What exactly is it? So I'll create a map in a map editor, and I will then have to create a 2D array to match that map, that's fine. Also, I'm not quite sure what's going on inside the collideCheck() function. they xPos and yPos are the coordinates of the car right? and tileXPos and tileYPos are the coordinates of the tile., obviously. what exactly is the operator /= together mean? thanks again, i am definitely understanding it now.
#21376 - keldon - Fri May 28, 2004 10:08 am
dagamer34 wrote: |
tepples wrote: | In, say, Mario Kart, road tiles can be "road" or "grass" or "wall". If the player is on a "road" tile, use "road" physics; likewise for "grass". If the player attempts to enter a "wall", move the player to the edge of the tile and bounce the player's velocity. |
I was thinking a little bit further. You could have some tiles that are 1/2 road and 1/2 grass with a diagon split. Something like this
Code: |
------
|//// |
|/// |
|// |
|/ |
------
|
It's supposed to be a tile, but that's not the point. If the grass was the white area, and the road the '/' area, and the split is at 45 degrees, you could use some math to create more interesting shapes and more intersting collisions. |
That's what my posts was explaining :-)
DigitalChaos when you see:
it also means
#21399 - dagamer34 - Fri May 28, 2004 7:54 pm
DigitalChaos wrote: |
Miked,
Thank you. I always understand much better seeing the actual code than I understand an explanation. I have never run across ASSERT(). What exactly is it? So I'll create a map in a map editor, and I will then have to create a 2D array to match that map, that's fine. Also, I'm not quite sure what's going on inside the collideCheck() function. they xPos and yPos are the coordinates of the car right? and tileXPos and tileYPos are the coordinates of the tile., obviously. what exactly is the operator /= together mean? thanks again, i am definitely understanding it now. |
ASSERT is a macro that automatically breaks from the program and returns an error value to the OS. Since we don't have an OS on the GBA, we have to make up our own. Most people simply send the error information to the debug screen and have a hanging loop. Here's what I'm talking about: What is ASSERT?
About Miked's code: It's simple collision detection. What you would do to use it is first get input from the player, then move the car, and then do a collision check. If the tile isn't clear, move the player back to where he was before and keep going.
If you feel you really understand this, then start moving on to more complex shapes (like diagonals). Hopefully you will, because pure square collisions are very unforgiving, especially if the tile is near a turn.
_________________
Little kids and Playstation 2's don't mix. :(
#21411 - sajiimori - Fri May 28, 2004 9:59 pm
Better yet, get this working first, then move on to greater things. =)