Bricklayer.Client.Entities.Player.ApplyPhysics C# (CSharp) Method

ApplyPhysics() private method

Apply client-side physics to the character, calculate velocity from movement and gravity, handle collisions
private ApplyPhysics ( GameTime gameTime ) : void
gameTime Microsoft.Xna.Framework.GameTime
return void
        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;
        }