Ejemplo n.º 1
0
    private void ChangeForm(PlayerForm form, bool instant = false)
    {
        IsChangingForm = true;
        CurrentForm    = form;

        GD.Print("Changing form to " + form.ToString());

        if (!SceneCache.ContainsKey(CurrentForm))
        {
            SceneCache.Add(CurrentForm, GD.Load <PackedScene>(Constants.FilePath.PLAYER_FORM_SCENES + CurrentForm.ToString() + ".tscn"));
        }
        CurrentScene = SceneCache[CurrentForm];

        string frameCacheKey = SpriteFolderName + "/" + CurrentForm.ToString();

        if (!FrameCache.ContainsKey(frameCacheKey))
        {
            FrameCache.Add(frameCacheKey, GD.Load <SpriteFrames>(Constants.FilePath.PLAYER_FRAMES + SpriteFolderName + "/" + CurrentForm.ToString() + ".tres"));
        }
        CurrentFrames = FrameCache[frameCacheKey];

        Player oldFormScene = GetChildCount() > 0 ? GetChildOrNull <Player>(0) : null;

        oldFormScene?.SetName("QueuedForDeletion");

        if (oldFormScene != null)
        {
            PreviousTransform = oldFormScene.GetGlobalTransform();
            PreviousVelocity  = oldFormScene.Velocity;

            AnimatedSprite3D sprite = GetNode <AnimatedSprite3D>(new NodePath("QueuedForDeletion/PlayerSprite"));
            PreviousSpriteFlipped = sprite.IsFlippedH();

            if (!instant)
            {
                //Create blinking state transition
                TransitionFrames.Clear("Transition");

                TransitionFrames.AddFrame("Transition", sprite.Frames.GetFrame(Player.PlayerAnimation.IDLE, 0), 0);
                TransitionFrames.AddFrame("Transition", CurrentFrames.GetFrame(Player.PlayerAnimation.IDLE, 0), 1);

                TransitionSprite.SetGlobalTransform(sprite.GetGlobalTransform().Translated(-Transform.origin));
                TransitionSprite.SetFlipH(sprite.FlipH);
                TransitionSprite.SetPixelSize(sprite.GetPixelSize());
                TransitionSprite.Play("Transition");
            }

            oldFormScene.SetProcess(false);
            oldFormScene.SetPhysicsProcess(false);
            oldFormScene.QueueFree();
        }

        if (instant)
        {
            FinishFormChange(form);
            return;
        }

        AddChild(TransitionSprite);
    }
Ejemplo n.º 2
0
    public override void AProcess(float delta)
    {
        //Flip the sprite correctly
        if (Input.GetActionStrength("p1_right") - Input.GetActionStrength("p1_left") > 0)
        {
            PlayerSprite.SetFlipH(false);
        }
        else if (Velocity.x < 0)
        {
            PlayerSprite.SetFlipH(true);
        }

        DebugText.Display("P1_Pos", "P1 Position: " + Transform.origin.ToString());
        DebugText.Display("P1_Vel", "P1 Velocity: " + Velocity.ToString());
        DebugText.Display("P1_Grnd", "P1 On Ground: " + IsOnFloor());
        DebugText.Display("P1_Snap", "P1 Ground Snap: " + SnapToGround);
    }
Ejemplo n.º 3
0
    public virtual void SetupPlayer(InputManager input, Transform transform, Vector3 velocity, SpriteFrames spriteFrames, bool spriteFlipped)
    {
        PlayerSprite      = GetNodeOrNull <AnimatedSprite3D>(new NodePath("PlayerSprite"));
        ActorDetectorArea = GetNodeOrNull <Area>(new NodePath("ActorDetector"));
        FloorRayCast      = GetNodeOrNull <RayCast>(new NodePath("FloorRayCast"));

        if (PlayerSprite == null || ActorDetectorArea == null || FloorRayCast == null)
        {
            GD.Print("One or multiple required child nodes could not be found! Some features won't work!");
        }

        InputManager = input;
        SetGlobalTransform(transform);
        Velocity            = velocity;
        PlayerSprite.Frames = spriteFrames;
        PlayerSprite.SetFlipH(spriteFlipped);

        SetPlayerCollisionShape(GetDefaultCollisionShape());
    }
Ejemplo n.º 4
0
    public override void AReady()
    {
        PlayerSprite      = GetNodeOrNull(new NodePath("PlayerSprite")) as AnimatedSprite3D;
        ActorDetectorArea = GetNodeOrNull(new NodePath("ActorDetector")) as Area;
        FloorRayCast      = GetNodeOrNull(new NodePath("FloorRayCast")) as RayCast;

        if (PlayerSprite == null || ActorDetectorArea == null || FloorRayCast == null)
        {
            GD.PrintErr("One or multiple required child nodes could not be found! Some features won't work!");
        }

        InputManager = new InputManager(PlayerNumber);

        StandState = new ActorState(() =>
        { //Enter State
            SnapToGround = true;
        }, (float delta) =>
        { //Process State
            if (Mathf.Abs(Velocity.x) > 0.5f)
            {
                PlayerSprite.SetAnimation(PlayerAnimation.WALK);
                PlayerSprite.Frames.SetAnimationSpeed(PlayerAnimation.WALK, (Mathf.Abs(Velocity.x)) + 5);
            }
            else
            {
                PlayerSprite.SetAnimation(PlayerAnimation.IDLE);
            }
        }, (float delta) =>
        { //State Physics Processing
            if (InputManager.DirectionalInput.x != 0)
            {
                ChangeState(WalkState);
            }
            CanFall();
            CanJump();
            CanCrouch();
        }, () =>
        { //Exit State
        });

        WalkState = new ActorState(() =>
        { //Enter State
            SetSpeedLimit(WalkSpeed);
            SnapToGround = true;
        }, (float delta) =>
        { //Process State
            if (Mathf.Sign(Velocity.x) == Mathf.Sign(InputManager.DirectionalInput.x) || Velocity.x == 0)
            {
                PlayerSprite.SetAnimation(PlayerAnimation.WALK);
                PlayerSprite.Frames.SetAnimationSpeed(PlayerAnimation.WALK, (Mathf.Abs(Velocity.x)) + 5);
            }
            else
            {
                PlayerSprite.SetAnimation(PlayerAnimation.TURN);
            }
        }, (float delta) =>
        { //State Physics Processing
            if (InputManager.DirectionalInput.x == 0)
            {
                ChangeState(StandState);
            }
            if (InputManager.RunPressed || InputManager.AltRunPressed)
            {
                ChangeState(RunState);
            }
            CanFall();
            CanJump();
            CanCrouch();

            float force = InputManager.DirectionalInput.x * WalkAcceleration;
            ApplyForce2D(new Vector2(force, 0));
        }, () =>
        { //Exit State
        });

        RunState = new ActorState(() =>
        { //Enter State
            SetSpeedLimit(RunSpeed);
            SnapToGround = true;
        }, (float delta) =>
        { //Process State
            if (Mathf.Sign(Velocity.x) == Mathf.Sign(InputManager.DirectionalInput.x) || Velocity.x == 0)
            {
                PlayerSprite.SetAnimation(PlayerAnimation.WALK);
                PlayerSprite.Frames.SetAnimationSpeed(PlayerAnimation.WALK, (Mathf.Abs(Velocity.x)) + 7);
            }
            else
            {
                PlayerSprite.SetAnimation(PlayerAnimation.TURN);
            }
        }, (float delta) =>
        { //State Physics Processing
            if (InputManager.DirectionalInput.x == 0)
            {
                ChangeState(StandState);
            }
            if (!InputManager.RunPressed && !InputManager.AltRunPressed)
            {
                ChangeState(WalkState);
            }
            if (GetElapsedTimeInState() > LongRunTime)
            {
                ChangeState(LongRunState);
            }
            CanFall();
            CanJump();
            CanCrouch();

            float force = InputManager.DirectionalInput.x * RunAcceleration;
            ApplyForce2D(new Vector2(force, 0));
        }, () =>
        { //Exit State
        });

        LongRunState = new ActorState(() =>
        { //Enter State
            PlayerSprite.SetAnimation(PlayerAnimation.LONG_RUN);
            SetSpeedLimit(LongRunSpeed);
            SnapToGround = true;
        }, (float delta) =>
        { //Process State
            if (Mathf.Sign(Velocity.x) == Mathf.Sign(InputManager.DirectionalInput.x) || Velocity.x == 0)
            {
                PlayerSprite.SetAnimation(PlayerAnimation.LONG_RUN);
                PlayerSprite.Frames.SetAnimationSpeed(PlayerAnimation.LONG_RUN, (Mathf.Abs(Velocity.x)) + 10);
            }
            else
            {
                PlayerSprite.SetAnimation(PlayerAnimation.TURN);
            }
        }, (float delta) =>
        { //State Physics Processing
            if (InputManager.DirectionalInput.x == 0)
            {
                ChangeState(StandState);
            }
            if (!InputManager.RunPressed && !InputManager.AltRunPressed || Mathf.Sign(Velocity.x) != Mathf.Sign(InputManager.DirectionalInput.x))
            {
                ChangeState(WalkState);
            }
            CanFall();
            CanJump();
            CanCrouch();

            float force = InputManager.DirectionalInput.x * LongRunAcceleration;
            ApplyForce2D(new Vector2(force, 0));
        }, () =>
        { //Exit State
        });

        JumpState = new ActorState(() =>
        { //Enter State
            SnapToGround = false;

            float speed = Mathf.Abs(Velocity.x);
            if (speed > RunSpeed)
            {
                ApplyForce2D(new Vector2(0, LongRunJumpForce));
                PlayerSprite.SetAnimation(PlayerAnimation.HIGH_JUMP);
            }
            else if (speed > 0.5f)
            {
                ApplyForce2D(new Vector2(0, WalkJumpForce));
                PlayerSprite.SetAnimation(PlayerAnimation.JUMP);
            }
            else if (PreviousState == CrouchState)
            {
                ApplyForce2D(new Vector2(0, IdleJumpForce));
                PlayerSprite.SetAnimation(PlayerAnimation.CROUCH);
                SetPlayerCollisionShape(PlayerCollisionShape.SMALL);
            }
            else
            {
                ApplyForce2D(new Vector2(0, IdleJumpForce));
                PlayerSprite.SetAnimation(PlayerAnimation.JUMP);
            }
        }, (float delta) =>
        { //Process State
          //DebugText.Display("P" + PlayerNumber + "_JumpSusTime", "P" + PlayerNumber + " Jump Sustain Time: " + (MaxJumpSustainTime - GetElapsedTimeInState()).ToString());
        }, (float delta) =>
        { //State Physics Processing
            if (IsOnFloor())
            {
                ChangeState(StandState);
            }
            if ((!InputManager.JumpPressed && !InputManager.AltJumpPressed) || GetElapsedTimeInState() > MaxJumpSustainTime)
            {
                ChangeState(FallState);
            }

            if (SpeedLimit >= LongRunSpeed && (InputManager.RunPressed || InputManager.AltRunPressed))
            {
                SetSpeedLimit(LongRunSpeed);
            }
            else if (InputManager.RunPressed || InputManager.AltRunPressed)
            {
                SetSpeedLimit(RunSpeed);
            }
            else
            {
                SetSpeedLimit(WalkSpeed);
            }

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

            float force = InputManager.DirectionalInput.x * AirHorizontalAcceleration;
            ApplyForce2D(new Vector2(force, 0));
        }, () =>
        { //Exit State
            //DebugText.Remove("P" + PlayerNumber + "_JumpSusTime");
            SetPlayerCollisionShape(GetDefaultCollisionShape());
        });

        SpinJumpState = new ActorState(() =>
        { //Enter State
            SnapToGround = false;
            PlayerSprite.SetAnimation(PlayerAnimation.SPIN_JUMP);

            float speed = Mathf.Abs(Velocity.x);
            if (speed > RunSpeed)
            {
                ApplyForce2D(new Vector2(0, LongRunJumpForce));
            }
            else if (speed > 0.5f)
            {
                ApplyForce2D(new Vector2(0, WalkJumpForce));
            }
            else if (PreviousState == CrouchState)
            {
                ApplyForce2D(new Vector2(0, IdleJumpForce));
            }
            else
            {
                ApplyForce2D(new Vector2(0, IdleJumpForce));
            }
        }, (float delta) =>
        { //Process State
          //DebugText.Display("P" + PlayerNumber + "_JumpSusTime", "P" + PlayerNumber + " Jump Sustain Time: " + (MaxJumpSustainTime - GetElapsedTimeInState()).ToString());
        }, (float delta) =>
        { //State Physics Processing
            if (IsOnFloor())
            {
                ChangeState(StandState);
            }
            if ((!InputManager.JumpPressed && !InputManager.AltJumpPressed) || GetElapsedTimeInState() > MaxJumpSustainTime)
            {
                ChangeState(FallState);
            }

            if (SpeedLimit >= LongRunSpeed && (InputManager.RunPressed || InputManager.AltRunPressed))
            {
                SetSpeedLimit(LongRunSpeed);
            }
            else if (InputManager.RunPressed || InputManager.AltRunPressed)
            {
                SetSpeedLimit(RunSpeed);
            }
            else
            {
                SetSpeedLimit(WalkSpeed);
            }

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

            float force = InputManager.DirectionalInput.x * AirHorizontalAcceleration;
            ApplyForce2D(new Vector2(force, 0));
        }, () =>
        { //Exit State
          //DebugText.Remove("P" + PlayerNumber + "_JumpSusTime");
        });

        FallState = new ActorState(() =>
        { //Enter State
            if (InputManager.DirectionalInput.y < CrouchInputThreshold)
            {
                PlayerSprite.SetAnimation(PlayerAnimation.CROUCH);
                SetPlayerCollisionShape(PlayerCollisionShape.SMALL);
            }
            else if (PreviousState == SpinJumpState)
            {
                PlayerSprite.SetAnimation(PlayerAnimation.SPIN_JUMP);
            }
            else
            {
                PlayerSprite.SetAnimation(PlayerAnimation.FALL);
            }
            SnapToGround = false;
        }, (float delta) =>
        { //Process State
        }, (float delta) =>
        { //State Physics Processing
            if (IsOnFloor())
            {
                if (InputManager.DirectionalInput.y < CrouchInputThreshold)
                {
                    ChangeState(CrouchState);
                }
                else
                {
                    ChangeState(StandState);
                }
            }

            if (SpeedLimit >= LongRunSpeed && (InputManager.RunPressed || InputManager.AltRunPressed))
            {
                SetSpeedLimit(LongRunSpeed);
            }
            else if (InputManager.RunPressed || InputManager.AltRunPressed)
            {
                SetSpeedLimit(RunSpeed);
            }
            else
            {
                SetSpeedLimit(WalkSpeed);
            }

            float force = InputManager.DirectionalInput.x * AirHorizontalAcceleration;
            ApplyForce2D(new Vector2(force, 0));
        }, () =>
        { //Exit State
            SetPlayerCollisionShape(GetDefaultCollisionShape());
        });

        CrouchState = new ActorState(() =>
        { //Enter State
            SnapToGround = true;

            var angle = Mathf.Rad2Deg(Mathf.Acos(FloorRayCast.GetCollisionNormal().Dot(FloorNormal)));
            if (angle >= SlideMinAngle)
            {
                ChangeState(SlideState);
                return;
            }

            PlayerSprite.SetAnimation(PlayerAnimation.CROUCH);
            SetPlayerCollisionShape(PlayerCollisionShape.SMALL);
        }, (float delta) =>
        { //Process State
        }, (float delta) =>
        { //State Physics Processing
            Transform slightlyRight;
            slightlyRight.origin    = Transform.origin;
            slightlyRight.basis     = Transform.basis;
            slightlyRight.origin.x += 0.4f;

            Transform slightlyLeft;
            slightlyLeft.origin    = Transform.origin;
            slightlyLeft.basis     = Transform.basis;
            slightlyLeft.origin.x -= 0.4f;

            if (!TestMove(Transform, new Vector3(0, 0.5f, 0)))
            {
                if (InputManager.DirectionalInput.y >= CrouchInputThreshold)
                {
                    ChangeState(StandState);
                }
                CanJump();
                CanFall();
            }
            else if (!TestMove(slightlyRight, new Vector3(0, 0.5f, 0)))
            {
                ApplyForce2D(new Vector2(0.4f, 0));
            }
            else if (!TestMove(slightlyLeft, new Vector3(0, 0.5f, 0)))
            {
                ApplyForce2D(new Vector2(-0.4f, 0));
            }
            else
            {
                if (InputManager.JumpJustPressed || InputManager.AltJumpJustPressed)
                {
                    ApplyForce2D(new Vector2(CrouchBoostForce.x * InputManager.DirectionalInput.x, CrouchBoostForce.y));
                }
            }
        }, () =>
        { //Exit State
            SetPlayerCollisionShape(GetDefaultCollisionShape());
        });

        SlideState = new ActorState(() =>
        { //Enter State
            SetSpeedLimit(SlideSpeed);
            SnapToGround = true;

            PlayerSprite.SetAnimation(PlayerAnimation.SLIDE);
            autoPlayerFacing = false;
        }, (float delta) =>
        { //Process State
            //Manually flip the sprite according to the movement direction
            if (Velocity.x > 0)
            {
                PlayerSprite.SetFlipH(false);
            }
            else if (Velocity.x < 0)
            {
                PlayerSprite.SetFlipH(true);
            }
        }, (float delta) =>
        { //State Physics Processing
            Vector3 normal = FloorRayCast.GetCollisionNormal();
            float angle    = Mathf.Rad2Deg(Mathf.Acos(normal.Dot(FloorNormal)));
            if (angle < SlideMinAngle)
            {
                ChangeState(InputManager.DirectionalInput.y < CrouchInputThreshold ? CrouchState : StandState);
            }
            CanFall();
            CanJump();

            float force = Mathf.Sign(normal.x) * SlideAcceleration;
            ApplyForce2D(new Vector2(force, 0));
        }, () =>
        { //Exit State
            autoPlayerFacing = true;
        });
    }