Example #1
0
    public override void APhysicsPostProcess(float delta)
    {
        //Apply friction
        if (CurrentState == CrouchState || CurrentState == SlideState)
        {
            Velocity.x = Mathf.Max(Mathf.Abs(Velocity.x) - SlideFriction, 0) * Mathf.Sign(Velocity.x);
        }
        else
        {
            Velocity.x = Mathf.Max((Mathf.Abs(Velocity.x) - (IsOnFloor() ? FloorFriction : AirFriction)), 0) * Mathf.Sign(Velocity.x);
        }

        //Lerp to speed limit if above
        if (Mathf.Abs(Velocity.x) > SpeedLimit)
        {
            Velocity.x = ClampedInterpolation.Lerp(SpeedLerpStartVelocity, SpeedLimit, (Lifetime - SpeedLerpStartTime) * (1 / SpeedLerpDuration)) * Mathf.Sign(Velocity.x);
        }

        //DebugText.Display("P" + PlayerNumber + "_SpeedLimit", "P" + PlayerNumber + " Speed Limit: " + SpeedLimit.ToString());
    }
Example #2
0
    public override void AEnterTree() //TODO Try moving everything non-visual to Physics Processing
    {
        PlayerSprite      = GetNodeOrNull(new NodePath("PlayerSprite")) as AnimatedSprite3D;
        ActorDetectorArea = GetNodeOrNull(new NodePath("ActorDetector")) as Area;

        if (PlayerSprite == null || ActorDetectorArea == null)
        {
            GD.PrintErr("One or multiple required child nodes could not be found!");
        }

        //Define states

        StandState = new ActorState(() =>
        { //Enter State
            PlayerSprite.SetAnimation("Idle");
            SnapToGround = true;
        }, (float delta) =>
        { //Process State
        }, (float delta) =>
        { //State Physics Processing
            //Switch to the walking state when directional input is given
            bool sideInput = Mathf.Abs(Input.GetActionStrength("p1_right") - Input.GetActionStrength("p1_left")) > 0;
            if (sideInput)
            {
                ChangeState(WalkState);
            }

            CanFall();
            CanJump();
        }, () =>
        { //Exit State
        });


        WalkState = new ActorState(() =>
        { //Enter State
            PlayerSprite.SetAnimation("Walk");
            SnapToGround = true;
        }, (float delta) =>
        { //Process State
        }, (float delta) =>
        { //State Physics Processing
            //Switch to the standing state when no directional input is given
            float sideInput = Input.GetActionStrength("p1_right") - Input.GetActionStrength("p1_left");
            if (sideInput == 0)
            {
                ChangeState(StandState);
            }

            //Check if the player should be running, if yes go to run state
            bool isRunPressed = Input.GetActionStrength("p1_run") > 0;
            if (isRunPressed)
            {
                ChangeState(RunState);
            }

            //Move the player
            Vector2 movement = new Vector2();
            movement.x       = sideInput * WalkAcceleration;
            //movement.x = Mathf.Abs(Velocity.x) + Mathf.Abs(movement.x) > MaxWalkSpeed ? (MaxWalkSpeed - Mathf.Abs(Velocity.x)) * Mathf.Sign(movement.x) : movement.x;
            ApplyForce2D(movement);

            //Update the walking animation speed
            PlayerSprite.Frames.SetAnimationSpeed("Walk", (Mathf.Abs(Velocity.x) / 2) + 8);

            CanFall();
            CanJump();

            //Enforce walk speed limit
            if (Math.Abs(Velocity.x) >= MaxWalkSpeed)
            {
                Velocity.x = ClampedInterpolation.Lerp(Velocity.x, MaxWalkSpeed * Mathf.Sign(Velocity.x), GetElapsedTimeInState());
            }
        }, () =>
        { //Exit State
        });


        RunState = new ActorState(() =>
        { //Enter State
            PlayerSprite.SetAnimation("Walk");
            SnapToGround = true;
        }, (float delta) =>
        { //Process State
        }, (float delta) =>
        { //State Physics Processing
            //Switch to the standing state when no directional input is given
            float sideInput = Input.GetActionStrength("p1_right") - Input.GetActionStrength("p1_left");
            if (sideInput == 0)
            {
                ChangeState(StandState);
            }

            //Check if the player should be running, if not go back to walk state
            bool isRunPressed = Input.GetActionStrength("p1_run") > 0;
            if (!isRunPressed)
            {
                ChangeState(WalkState);
            }

            //Move the player
            Vector2 movement = new Vector2();
            movement.x       = sideInput * RunAcceleration;
            //movement.x = Mathf.Abs(Velocity.x) + Mathf.Abs(movement.x) > MaxRunSpeed ? (MaxRunSpeed - Mathf.Abs(Velocity.x)) * Mathf.Sign(movement.x) : movement.x;
            ApplyForce2D(movement);

            //Update the walking animation speed
            PlayerSprite.Frames.SetAnimationSpeed("Walk", Mathf.Max((Mathf.Abs(Velocity.x)) + 2, (Mathf.Abs(Velocity.x) / 2) + 8));

            CanFall();
            CanJump();

            //Enforce walk speed limit
            if (Math.Abs(Velocity.x) >= MaxRunSpeed)
            {
                Velocity.x = ClampedInterpolation.Lerp(Velocity.x, MaxRunSpeed * Mathf.Sign(Velocity.x), GetElapsedTimeInState());
            }
        }, () =>
        { //Exit State
        });


        JumpState = new ActorState(() =>
        { //Enter State
            GD.Print("Jump");

            PlayerSprite.SetAnimation("Jump");
            SnapToGround = false;

            JumpSpeedBuffer = Velocity.x;

            //Add the initial force of the jump
            ApplyForce2D(new Vector2(0, JumpSpeed));
        }, (float delta) =>
        { //Process State
        }, (float delta) =>
        { //State Physics Processing
            float jumpTime = GetElapsedTimeInState();
            DebugText.Display("jumpTime", "Jump Time: " + jumpTime);

            //Add some force for extra air time if the jump button is held
            ApplyForce2D(Vector2.Up, Gravity.y * (1 - JumpSustainGravityMultiplier));

            //Allow slight player movement
            float sideInput  = Input.GetActionStrength("p1_right") - Input.GetActionStrength("p1_left");
            Vector2 movement = new Vector2();
            movement.x       = sideInput * (AirAcceleration);
            ApplyForce2D(movement);

            //Exit state if required
            bool jumpPressed = Input.GetActionStrength("p1_jump") > 0;
            if (!jumpPressed || jumpTime > MaxJumpTime)
            {
                ChangeState(FallState);
            }
            if (IsOnFloor())
            {
                ChangeState(StandState);
            }

            //Enforce air speed limit
            float speedLimit = Mathf.Min(Mathf.Abs(JumpSpeedBuffer), MaxRunSpeed);
            if (Mathf.Abs(Velocity.x) >= speedLimit)
            {
                Velocity.x = ClampedInterpolation.Lerp(Velocity.x, speedLimit * Mathf.Sign(Velocity.x), GetElapsedTimeInState());
            }
        }, () =>
        { //Exit State
            DebugText.Remove("jumpTime");
        });


        FallState = new ActorState(() =>
        { //Enter State
            GD.Print("Fall");

            SnapToGround = false;
            PlayerSprite.SetAnimation("Jump");

            JumpSpeedBuffer = Velocity.x;
        }, (float delta) =>
        { //Process State
        }, (float delta) =>
        { //State Physics Processing
            //Allow slight player movement
            float sideInput  = Input.GetActionStrength("p1_right") - Input.GetActionStrength("p1_left");
            Vector2 movement = new Vector2();
            movement.x       = sideInput * (AirAcceleration);
            ApplyForce2D(movement);

            if (IsOnFloor() == true)
            {
                ChangeState(StandState);
            }

            //Enforce air speed limit

            /* if(PreviousState == RunState) {
             *  if (Math.Abs(Velocity.x) > MaxRunSpeed) { Velocity.x = Interpolation.Lerp(Velocity.x, MaxRunSpeed * Mathf.Sign(Velocity.x), GetElapsedTimeInState()); }
             * } else {
             *  if (Math.Abs(Velocity.x) > MaxWalkSpeed) { Velocity.x = Interpolation.Lerp(Velocity.x, MaxWalkSpeed * Mathf.Sign(Velocity.x), GetElapsedTimeInState()); }
             * } */
            float speedLimit = Mathf.Min(Mathf.Abs(JumpSpeedBuffer), MaxRunSpeed);
            if (Mathf.Abs(Velocity.x) >= speedLimit)
            {
                Velocity.x = ClampedInterpolation.Lerp(Velocity.x, speedLimit * Mathf.Sign(Velocity.x), GetElapsedTimeInState());
            }
        }, () =>
        { //Exit State
        });
    }