Original Post
Hello,
I'm developing a collision system for my little isometric engine. I have a PlayerEntity Class with a property
[source lang="csharp"]///
/// Get or set the position of this entity
///
public Vector2 Location
{
get { return _location; }
set
{
_location = value;
Rectangle = new Rectangle( (int)value.X, (int)value.Y, Rectangle.Width, Rectangle.Height );
if( Fixture != null )
Fixture.Location = value;
}
}
private Vector2 _location;[/source]
The rectangle field doesn't need any explanation. Well, what is a fixture? the Fixture is a Class needed for collision detection. Every fixture has his shape, for example
[source lang="csharp"]public enum FixtureShape
{
Rectangle,
Circle,
Rhomb,
MouseMap,
None
}[/source]
For example,
here the violet circle is the fixture for the player entity. For other shapes is similiar. If mouse map is choosen, the texture is thresholded and for every pixel with an alpha value different from zero, that pixel is set to black. Well, for collision detection i use per pixel collision algorithm, for now i use that from microsoft sample. Here's the function
[source lang="csharp"]public bool CheckCollision( Fixture f )
{
Rectangle f2Rect = f.Rectangle;
Color[] f2Data = f.FixtureData;
// Find the bounds of the rectangle intersection
int top = Math.Max( Rectangle.Top, f2Rect.Top );
int bottom = Math.Min( Rectangle.Bottom, f2Rect.Bottom );
int left = Math.Max( Rectangle.Left, f2Rect.Left );
int right = Math.Min( Rectangle.Right, f2Rect.Right );
// Check every point within the intersection bounds
for( int y = top; y < bottom; y++ )
{
for( int x = left; x < right; x++ )
{
// Get the color of both pixels at this point
Color colorA = FixtureData[ ( x - Rectangle.Left ) +
( y - Rectangle.Top ) * Rectangle.Width ];
Color colorB = f2Data[ ( x - f2Rect.Left ) +
( y - f2Rect.Top ) * f2Rect.Width ];
// If both pixels are not completely transparent,
if( colorA.A != 0 && colorB.A != 0 )
{
// then an intersection has been found
return true;
}
}
}
// No intersection found
return false;
}[/source]
And here's how i use it. I have a list of fixtures that are currently in the visible part of the screen, viewedFixtures. Here's the function where i check collision between objects and player
[source lang="csharp"]public bool IsPlayerColliding( List viewedFixtures, Vector2 MoveDirection )
{
if( PlayerFixture == null )
return false;
//take a clone of player fixture
Fixture t = (Fixture)PlayerFixture.Clone();
t.Location += MoveDirection;
foreach( Fixture f in viewedFixtures )
{
if( t.CheckCollision( f ) )
//there's a collision
return true;
}
return false;
}[/source]
what i do here is checking for collision between the player fixture, moved along the direction the user choosed, and the near fixtures, and this is the function that let the user to move the player in the map:
[source lang="csharp"]public void MovePlayer( Vector2 moveDirection )
{
if( Player == null )
return;
if( !CollisionSystem.IsPlayerColliding( Map.ViewedFixtures, moveDirection ) )
{
Player.Location += moveDirection;
}
}[/source]
here, if the fixture in the new location is not colliding, finally move the player and the player fixture along the choosed direction. Finally, here's the update method of the game source:
[source lang="csharp"]///
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
///
/// Provides a snapshot of timing values.
protected override void Update( GameTime gameTime )
{
// Allows the game to exit
if( GamePad.GetState( PlayerIndex.One ).Buttons.Back == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
this.Exit();
GamePadState padState = GamePad.GetState( PlayerIndex.One );
Vector2 MoveDirection = Vector2.Zero;
#region Movement section
#region North-west
if( padState.DPad.Left == Microsoft.Xna.Framework.Input.ButtonState.Pressed && padState.DPad.Up == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( -2, -1 );
}
else
#endregion North-west
#region North-east
if( padState.DPad.Right == Microsoft.Xna.Framework.Input.ButtonState.Pressed && padState.DPad.Up == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( 2, -1 );
}
#endregion North-east
#region South-west
else
if( padState.DPad.Left == Microsoft.Xna.Framework.Input.ButtonState.Pressed && padState.DPad.Down == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( -2, 1 );
}
#endregion South-west
#region South-east
else
if( padState.DPad.Right == Microsoft.Xna.Framework.Input.ButtonState.Pressed && padState.DPad.Down == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( 2, 1 );
}
#endregion South-east
#region North
else
if( padState.DPad.Up == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( 0, -1 );
}
#endregion North
#region South
else
if( padState.DPad.Down == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( 0, 1 );
}
#endregion South
#region West
else
if( padState.DPad.Left == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( -2, 0 );
}
#endregion West
#region East
else
if( padState.DPad.Right == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( 2, 0 );
}
#endregion East
#endregion Movement section
if( MoveDirection != Vector2.Zero )
world.MovePlayer( MoveDirection );
base.Update( gameTime );
}[/source]
Ok. There's a problem but i can't find it. Here's some screenshot:


The problem is that the fixture go 'inside' the other fixture...anyone has a suggestion? (sorry for my bad english)
Thanks,
bye
I'm developing a collision system for my little isometric engine. I have a PlayerEntity Class with a property
[source lang="csharp"]///
/// Get or set the position of this entity
///
public Vector2 Location
{
get { return _location; }
set
{
_location = value;
Rectangle = new Rectangle( (int)value.X, (int)value.Y, Rectangle.Width, Rectangle.Height );
if( Fixture != null )
Fixture.Location = value;
}
}
private Vector2 _location;[/source]
The rectangle field doesn't need any explanation. Well, what is a fixture? the Fixture is a Class needed for collision detection. Every fixture has his shape, for example
[source lang="csharp"]public enum FixtureShape
{
Rectangle,
Circle,
Rhomb,
MouseMap,
None
}[/source]
For example,
here the violet circle is the fixture for the player entity. For other shapes is similiar. If mouse map is choosen, the texture is thresholded and for every pixel with an alpha value different from zero, that pixel is set to black. Well, for collision detection i use per pixel collision algorithm, for now i use that from microsoft sample. Here's the function[source lang="csharp"]public bool CheckCollision( Fixture f )
{
Rectangle f2Rect = f.Rectangle;
Color[] f2Data = f.FixtureData;
// Find the bounds of the rectangle intersection
int top = Math.Max( Rectangle.Top, f2Rect.Top );
int bottom = Math.Min( Rectangle.Bottom, f2Rect.Bottom );
int left = Math.Max( Rectangle.Left, f2Rect.Left );
int right = Math.Min( Rectangle.Right, f2Rect.Right );
// Check every point within the intersection bounds
for( int y = top; y < bottom; y++ )
{
for( int x = left; x < right; x++ )
{
// Get the color of both pixels at this point
Color colorA = FixtureData[ ( x - Rectangle.Left ) +
( y - Rectangle.Top ) * Rectangle.Width ];
Color colorB = f2Data[ ( x - f2Rect.Left ) +
( y - f2Rect.Top ) * f2Rect.Width ];
// If both pixels are not completely transparent,
if( colorA.A != 0 && colorB.A != 0 )
{
// then an intersection has been found
return true;
}
}
}
// No intersection found
return false;
}[/source]
And here's how i use it. I have a list of fixtures that are currently in the visible part of the screen, viewedFixtures. Here's the function where i check collision between objects and player
[source lang="csharp"]public bool IsPlayerColliding( List
{
if( PlayerFixture == null )
return false;
//take a clone of player fixture
Fixture t = (Fixture)PlayerFixture.Clone();
t.Location += MoveDirection;
foreach( Fixture f in viewedFixtures )
{
if( t.CheckCollision( f ) )
//there's a collision
return true;
}
return false;
}[/source]
what i do here is checking for collision between the player fixture, moved along the direction the user choosed, and the near fixtures, and this is the function that let the user to move the player in the map:
[source lang="csharp"]public void MovePlayer( Vector2 moveDirection )
{
if( Player == null )
return;
if( !CollisionSystem.IsPlayerColliding( Map.ViewedFixtures, moveDirection ) )
{
Player.Location += moveDirection;
}
}[/source]
here, if the fixture in the new location is not colliding, finally move the player and the player fixture along the choosed direction. Finally, here's the update method of the game source:
[source lang="csharp"]///
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
///
/// Provides a snapshot of timing values.
protected override void Update( GameTime gameTime )
{
// Allows the game to exit
if( GamePad.GetState( PlayerIndex.One ).Buttons.Back == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
this.Exit();
GamePadState padState = GamePad.GetState( PlayerIndex.One );
Vector2 MoveDirection = Vector2.Zero;
#region Movement section
#region North-west
if( padState.DPad.Left == Microsoft.Xna.Framework.Input.ButtonState.Pressed && padState.DPad.Up == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( -2, -1 );
}
else
#endregion North-west
#region North-east
if( padState.DPad.Right == Microsoft.Xna.Framework.Input.ButtonState.Pressed && padState.DPad.Up == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( 2, -1 );
}
#endregion North-east
#region South-west
else
if( padState.DPad.Left == Microsoft.Xna.Framework.Input.ButtonState.Pressed && padState.DPad.Down == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( -2, 1 );
}
#endregion South-west
#region South-east
else
if( padState.DPad.Right == Microsoft.Xna.Framework.Input.ButtonState.Pressed && padState.DPad.Down == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( 2, 1 );
}
#endregion South-east
#region North
else
if( padState.DPad.Up == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( 0, -1 );
}
#endregion North
#region South
else
if( padState.DPad.Down == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( 0, 1 );
}
#endregion South
#region West
else
if( padState.DPad.Left == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( -2, 0 );
}
#endregion West
#region East
else
if( padState.DPad.Right == Microsoft.Xna.Framework.Input.ButtonState.Pressed )
{
MoveDirection = new Vector2( 2, 0 );
}
#endregion East
#endregion Movement section
if( MoveDirection != Vector2.Zero )
world.MovePlayer( MoveDirection );
base.Update( gameTime );
}[/source]
Ok. There's a problem but i can't find it. Here's some screenshot:


The problem is that the fixture go 'inside' the other fixture...anyone has a suggestion? (sorry for my bad english)
Thanks,
bye