#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# Simple math function for 2D distances...

Fayetteville, NC, USAMember Posts: 1,035
[b][red]This message was edited by Moderator at 2003-6-3 9:50:30[/red][/b][hr]
OK, I've been toying with a 2D engine in OpenGL in my spare time and it actually started turning out nice, so I'm pursuing it. I'm to the point in the game-engine where I need to get the distances to the closest tiles to the player so I know if the player is about to collide or has collided with the object. Here's the first part of my test. It should return the distance to the closest tile.
[code]
/*
Notes:
POSITION is a struct with four float values.
X and Y are the upper-left coordinates of the player
U is how far the player is trying to move right or left
V is how far the player is trying to move up or down
*/

float MoveVertical(POSITION VPos)
{
float MVTest = [blue]256.000[/blue];

if(VPos.V == 0.000)
return 0.000;

for(short int MVBLoop = 0; MVBLoop < Map->numBlocks; MVBLoop++)
{
if(VPos.V < 0.000)
if((Map->Block[MVBLoop].Y < VPos.Y) && (Map->Block[MVBLoop].Y >= (VPos.Y - 128)))
if((Map->Block[MVBLoop].X <= (VPos.X + [red]64[/red])) || (Map->Block[MVBLoop].X >= (VPos.X - 32)))
{
//Block is within 32 units right or left and is within 128 units above, so test!
if(((VPos.Y - Map->Block[MVBLoop].Y) < MVTest))
MVTest = (VPos.Y - Map->Block[MVBLoop].Y);
}

if(VPos.V > 0.000)
if((Map->Block[MVBLoop].Y > VPos.Y) && (Map->Block[MVBLoop].Y <= (VPos.Y + [red]192[/red])))
if((Map->Block[MVBLoop].X <= (VPos.X + [red]64[/red])) || (Map->Block[MVBLoop].X >= (VPos.X - 32)))
{
//Block is within 32 units right or left and is within 128 units below, so test!
if(((Map->Block[MVBLoop].Y - VPos.Y) < MVTest))
MVTest = (Map->Block[MVBLoop].Y - VPos.Y);
}
}

return MVTest;
}
[/code]
For now, the engine works with tiles simply by specifying the upper-left coordinate in 2D space and each tile is only 32x32. Does this look correct to you people? The horizontal test is going to be identical, only testing tiles right and left of the player instead of above or below.

[red]*EDIT*[/red]

Made some changes to the source I noticed where I didn't take into account the size of the player image, which is 32 wide and 64 tall. Changes are in red.

[blue]*EDIT*[/blue]

Also figured out that if I always tested for everything except 0.000, I'd never figure out when a real collision happens! Changed the default value of the variable to double the distance we're testing, so it can ONLY decrease.

-[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]

• Member Posts: 642
Ok, looks like you are writing an RPG. At the moment its looks ok, so my next question comes down to does it work ?. But does it test for all blocks in the map or for maps that can be seen on screen only ? As far as I have experiences in my limited knowldge of game programming the collision largely depends on the game.

: [b][red]This message was edited by Moderator at 2003-6-3 9:50:30[/red][/b][hr]
: OK, I've been toying with a 2D engine in OpenGL in my spare time and it actually started turning out nice, so I'm pursuing it. I'm to the point in the game-engine where I need to get the distances to the closest tiles to the player so I know if the player is about to collide or has collided with the object. Here's the first part of my test. It should return the distance to the closest tile.
: [code]
: /*
: Notes:
: POSITION is a struct with four float values.
: X and Y are the upper-left coordinates of the player
: U is how far the player is trying to move right or left
: V is how far the player is trying to move up or down
: */
:
: float MoveVertical(POSITION VPos)
: {
: float MVTest = [blue]256.000[/blue];
:
: if(VPos.V == 0.000)
: return 0.000;
:
: for(short int MVBLoop = 0; MVBLoop < Map->numBlocks; MVBLoop++)
: {
: if(VPos.V < 0.000)
: if((Map->Block[MVBLoop].Y < VPos.Y) && (Map->Block[MVBLoop].Y >= (VPos.Y - 128)))
: if((Map->Block[MVBLoop].X <= (VPos.X + [red]64[/red])) || (Map->Block[MVBLoop].X >= (VPos.X - 32)))
: {
: //Block is within 32 units right or left and is within 128 units above, so test!
: if(((VPos.Y - Map->Block[MVBLoop].Y) < MVTest))
: MVTest = (VPos.Y - Map->Block[MVBLoop].Y);
: }
:
: if(VPos.V > 0.000)
: if((Map->Block[MVBLoop].Y > VPos.Y) && (Map->Block[MVBLoop].Y <= (VPos.Y + [red]192[/red])))
: if((Map->Block[MVBLoop].X <= (VPos.X + [red]64[/red])) || (Map->Block[MVBLoop].X >= (VPos.X - 32)))
: {
: //Block is within 32 units right or left and is within 128 units below, so test!
: if(((Map->Block[MVBLoop].Y - VPos.Y) < MVTest))
: MVTest = (Map->Block[MVBLoop].Y - VPos.Y);
: }
: }
:
: return MVTest;
: }
: [/code]
: For now, the engine works with tiles simply by specifying the upper-left coordinate in 2D space and each tile is only 32x32. Does this look correct to you people? The horizontal test is going to be identical, only testing tiles right and left of the player instead of above or below.
:
: [red]*EDIT*[/red]
:
: Made some changes to the source I noticed where I didn't take into account the size of the player image, which is 32 wide and 64 tall. Changes are in red.
:
: [blue]*EDIT*[/blue]
:
: Also figured out that if I always tested for everything except 0.000, I'd never figure out when a real collision happens! Changed the default value of the variable to double the distance we're testing, so it can ONLY decrease.
:
: -[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]
:
:
:
:
:
:
: