Background: I've been doing a lot of studying in xna lately. I've been perfecting my game structure and creating essential classes for an average game, read a couple articles, watched a number of videos, and read bits of a book I have. So, after creating a good game structure I moved on to the actual game, a platformer. I currently have ordinary blocks, and a Player - and the problem is within the player.
Problem/Question: Colliding with blocks is usually fine, but sometimes collisions act strangely. IE: Some how the player is in the block ( normally one pixel in ), and this is a big problem because this could cause the player to be pushed some where across the map.
Player Game Logic: The player's movement is state based. The states are an enumerator of "ground, jump, and fall". Right now, the problem seems to be inside of the falling state. Sometimes the collision works correct, sometimes the player ends up one pixel inside of the block - which means if the player jumps he will be instantly pushed to the first block above the player - no matter how far.
Collision Logic: Inside the fall state the player is pushed towards the floor by gravity. Gravity gets added by the force every frame. Before changing the position, a collision method is called upon checking if there was a collision between any block within it's range of motion. Now, since this is a falling state the player is moving down, so when it collides a while loop pushes the player down by 1pixel every frame until it's meeting the block. And just as a back up, there's a loop that pushes the player out of the block. Then it sets the current state to ground. The jumping state follows the same kind of theory.
Falling State Script: Read above for explanation of this code.
case PlayerState.Fall:
// falling sprite
mySpriteManager.mySpriteCurrent = mySpriteManager.mySpriteIndex["PlayerSprites/player_fall"];
// fall velocity change
myVelocity.Y += myDforce;
if ( Collision( otObjectList.wallIndex, myPosition.X + 1, myPosition.Y, myPosition.X + myWidth - 1, myPosition.Y + myHeight + myVelocity.Y) )
{
while( !Collision( otObjectList.wallIndex, myPosition.X + 1, myPosition.Y, myPosition.X + myWidth - 1, myPosition.Y + myHeight) )
myPosition.Y += 1;
while ( Collision(otObjectList.wallIndex, myPosition.X + 1, myPosition.Y, myPosition.X + myWidth - 1, myPosition.Y + myHeight))
myPosition.Y -= 1;
myVelocity.Y = 0;
myCurrentState = PlayerState.Ground;
}
else
{
myPosition.Y += myVelocity.Y;
}
break;
Collision Script: This runs through all solid objects until there is a collision and returns true if there is.
private bool Collision( List<ObjWall> otWalls, float x1, float y1, float x2, float y2)
{
myBoundingBox.X = (int)Math.Ceiling(x1);
myBoundingBox.Y = (int)Math.Ceiling(y1);
myBoundingBox.Width = (int)Math.Ceiling(Math.Abs( x2 - x1));
myBoundingBox.Height = (int)Math.Ceiling(Math.Abs( y2 - y1));
foreach (ObjWall wall in otWalls)
{
if ( Box.Intersects( wall.Box ) )
{
return true;
}
}
return false;
}
Variable Explanations:
myBoundingBox - every normal object builds off this abstract class. So, every object has a bounding rectangle.
Box - is a trait that comes from the abstract object class, it just returns the bounding rectangle.
myVelocity - is the players velocity, this is a Vector2 because floats provide cleaner looking gravity.
myDforce - is a float that changes the yvelocity in a positive force. I believe I should make it a constant.
ObjectList - this is a class that runs all Normal Object logic and contains a list of all the possible objects that can be in a room.
myPosition - This is another protected variable provided by the abstract class that normal objects are driven from. This is a vector 2, so it works using Floats.
For any more explanation in the code please ask! In advance, thanks for your time and Help. Cay.
myPosition.X
andmyPosition.Y
represent on the player? (i.e. top left/bottom left/bottom right etc.) – thudbutt