private void ApplyPhysics(GameTime gameTime)
{
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; //Time in seconds, since last frame
float delta = elapsed * 60;
//Face the direction the player is moving
if (SimulationState.Movement.X > 0)
Direction = FacingDirection.Right;
else if (SimulationState.Movement.X < 0)
Direction = FacingDirection.Left;
if (Mode == PlayerMode.Normal)
{
if (!IsMine)
IsJumping = VirtualJump;
//The next area applies the movement and gravity, based on the current direction the player is being pushed by arrows (if so)
//If gravity is up or down
if (GravityDirection == GravityDirection.Default || GravityDirection == GravityDirection.Down || GravityDirection == GravityDirection.Up)
{
//Apply horizontal movement
//If not movement detected from keys, apply acceleration to move, if not, slowly stop
if (SimulationState.Movement.X != 0)
SimulationState.Velocity.X += SimulationState.Movement.X * MoveSpeed;
else
SimulationState.Velocity.X = MathHelper.Lerp(SimulationState.Velocity.X, 0, MoveSlowDownFactor);
SimulationState.Velocity.X = MathHelper.Clamp(SimulationState.Velocity.X, -MaxVelocity, MaxVelocity);
//Apply vertical movement (jump, gravity)
if (GravityDirection == GravityDirection.Up)
{
SimulationState.Velocity.Y = MathHelper.Clamp((SimulationState.Velocity.Y - GravityAcceleration * .0166f) - GravityAcceleration * .0166f, -MaxFallSpeed, MaxFallSpeed);
SimulationState.Velocity.Y = DoJump(SimulationState.Velocity.Y, gameTime);
SimulationState.Velocity.Y = MathHelper.Clamp((SimulationState.Velocity.Y - GravityAcceleration * .0166f), -MaxFallSpeed, MaxFallSpeed);
}
else if (GravityDirection == GravityDirection.Down)
{
SimulationState.Velocity.Y = MathHelper.Clamp(((SimulationState.Velocity.Y + (GravityAcceleration * 2.5f) * .0166f) + (GravityAcceleration * 2.5f) * .0166f), -MaxFallSpeed, MaxFallSpeed);
SimulationState.Velocity.Y = DoJump(SimulationState.Velocity.Y, gameTime);
SimulationState.Velocity.Y = MathHelper.Clamp(((SimulationState.Velocity.Y + (GravityAcceleration * 2.5f) * .0166f)), -MaxFallSpeed, MaxFallSpeed);
}
else
{
SimulationState.Velocity.Y = MathHelper.Clamp((SimulationState.Velocity.Y + GravityAcceleration * .0166f) + GravityAcceleration * .0166f, -MaxFallSpeed, MaxFallSpeed);
SimulationState.Velocity.Y = DoJump(SimulationState.Velocity.Y, gameTime);
SimulationState.Velocity.Y = MathHelper.Clamp(SimulationState.Velocity.Y + GravityAcceleration * .0166f, -MaxFallSpeed, MaxFallSpeed);
}
}
//If gravity is left or right
if (GravityDirection == GravityDirection.Left || GravityDirection == GravityDirection.Right)
{
//Apply vertical movement
//If not movement detected from keys, apply acceleration to move, if not, slowly stop
if (SimulationState.Movement.Y != 0)
SimulationState.Velocity.Y += SimulationState.Movement.Y * MoveSpeed;
else
SimulationState.Velocity.Y = MathHelper.Lerp(SimulationState.Velocity.Y, 0, MoveSlowDownFactor);
SimulationState.Velocity.Y = MathHelper.Clamp(SimulationState.Velocity.Y, -MaxVelocity, MaxVelocity);
//Apply vertical movement (jump, gravity)
if (GravityDirection == GravityDirection.Left)
{
SimulationState.Velocity.X = MathHelper.Clamp((SimulationState.Velocity.X - GravityAcceleration * .0166f) - GravityAcceleration * .0166f, -MaxFallSpeed, MaxFallSpeed);
SimulationState.Velocity.X = DoJump(SimulationState.Velocity.X, gameTime);
SimulationState.Velocity.X = MathHelper.Clamp((SimulationState.Velocity.X - GravityAcceleration * .0166f), -MaxFallSpeed, MaxFallSpeed);
}
else if (GravityDirection == GravityDirection.Right)
{
SimulationState.Velocity.X = MathHelper.Clamp(((SimulationState.Velocity.X + GravityAcceleration * .0166f) + GravityAcceleration * .0166f), -MaxFallSpeed, MaxFallSpeed);
SimulationState.Velocity.X = DoJump(SimulationState.Velocity.X, gameTime);
SimulationState.Velocity.X = MathHelper.Clamp(((SimulationState.Velocity.X + GravityAcceleration * .0166f)), -MaxFallSpeed, MaxFallSpeed);
}
}
//Apply pseudo-drag horizontally.
if (IsOnGround)
SimulationState.Velocity.X *= GroundDragFactor;
else
SimulationState.Velocity.X *= AirDragFactor;
//If gravity is up or down, apply horizontal collision, then vertical
if (GravityDirection == GravityDirection.Default || GravityDirection == GravityDirection.Down || GravityDirection == GravityDirection.Up)
{
GravityDirection = GravityDirection.Default;
HorizontalCollision(gameTime, elapsed); //Horizontal Collison, X Axis
VerticalCollision(gameTime, elapsed); //Vertical Collision, Y Axis
}
//If gravity is left or right, apply vertical collision, then horizontal
else if (GravityDirection == GravityDirection.Left || GravityDirection == GravityDirection.Right)
{
GravityDirection = GravityDirection.Default;
VerticalCollision(gameTime, elapsed); //Vertical Collision, Y Axis
HorizontalCollision(gameTime, elapsed); //Horizontal Collison, X Axis
}
//If the collision stopped us from moving, reset the velocity to zero.
if (SimulationState.Position.X == PreviousState.Position.X)
SimulationState.Velocity.X = 0;
if (SimulationState.Position.Y == PreviousState.Position.Y)
SimulationState.Velocity.Y = 0;
}
else if (Mode == PlayerMode.God)
{
//If not movement detected from keys, apply acceleration to move, if not, slowly stop
if (SimulationState.Movement.X != 0)
SimulationState.Velocity.X += SimulationState.Movement.X * GodMoveSpeed;
else
SimulationState.Velocity.X = MathHelper.Lerp(SimulationState.Velocity.X, 0, GodMoveSlowDownFactor);
if (SimulationState.Movement.Y != 0)
SimulationState.Velocity.Y += SimulationState.Movement.Y * GodMoveSpeed;
else
SimulationState.Velocity.Y = MathHelper.Lerp(SimulationState.Velocity.Y, 0, GodMoveSlowDownFactor);
SimulationState.Velocity.X = MathHelper.Clamp(SimulationState.Velocity.X, -MaxGodVelocity, MaxGodVelocity);
SimulationState.Velocity.Y = MathHelper.Clamp(SimulationState.Velocity.Y, -MaxGodVelocity, MaxGodVelocity);
//X Axis
SimulationState.Velocity.X *= delta;
Vector2 change = SimulationState.Velocity.X * Vector2.UnitX * .0166f;
change.X = MathHelper.Clamp(change.X, -10, 10);
SimulationState.Position += change;
SimulationState.Position = new Vector2((float)Math.Round(SimulationState.Position.X), SimulationState.Position.Y);
//Y Axis
SimulationState.Velocity.Y *= delta;
change = SimulationState.Velocity.Y * Vector2.UnitY * .0166f;
change.Y = MathHelper.Clamp(change.Y, -10, 10);
SimulationState.Position += change;
SimulationState.Position = new Vector2(SimulationState.Position.X, (float)Math.Round(SimulationState.Position.Y));
//Stop velocity if player hits edge
if (SimulationState.Position.X < Tile.Width || SimulationState.Position.X > (Map.Width * Tile.Width) - (Tile.Width * 2))
SimulationState.Velocity.X = 0;
if (SimulationState.Position.Y < Tile.Height || SimulationState.Position.Y > (Map.Height * Tile.Height) - (Tile.Height * 2))
SimulationState.Velocity.Y = 0;
//Clamp position in bounds
SimulationState.Position.X = MathHelper.Clamp(SimulationState.Position.X, Tile.Width, (Map.Width * Tile.Width) - (Tile.Width * 2));
SimulationState.Position.Y = MathHelper.Clamp(SimulationState.Position.Y, Tile.Height, (Map.Height * Tile.Height) - (Tile.Height * 2));
}
//Set idle states
if (SimulationState.Position == PreviousState.Position)
IdleTime += elapsed;
else
IdleTime = 0;
}