Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / role / Player.cs
@小李xl 小李xl on 5 Jul 2023 8 KB 使用主动道具
using Godot;


/// <summary>
/// 玩家角色基类, 所有角色都必须继承该类
/// </summary>
[Tool]
public partial class Player : Role
{
    /// <summary>
    /// 获取当前操作的角色
    /// </summary>
    public static Player Current { get; private set; }

    /// <summary>
    /// 设置当前操作的玩家对象
    /// </summary>
    public static void SetCurrentPlayer(Player player)
    {
        Current = player;
        //设置相机和鼠标跟随玩家
        GameCamera.Main.SetFollowTarget(player);
        GameApplication.Instance.Cursor.SetMountRole(player);
    }
    
    public override void OnInit()
    {
        base.OnInit();
        
        AttackLayer = PhysicsLayer.Wall | PhysicsLayer.Prop | PhysicsLayer.Enemy;
        Camp = CampEnum.Camp1;

        //让相机跟随玩家
        // var remoteTransform = new RemoteTransform2D();
        // AddChild(remoteTransform);
        // MainCamera.Main.GlobalPosition = GlobalPosition;
        // MainCamera.Main.ResetSmoothing();
        // remoteTransform.RemotePath = remoteTransform.GetPathTo(MainCamera.Main);

        MaxHp = 6;
        Hp = 6;
        MaxShield = 0;
        Shield = 0;

        // debug用
        // Acceleration = 3000;
        // Friction = 3000;
        // MoveSpeed = 500;
        // CollisionLayer = 0;
        // CollisionMask = 0;
        // GameCamera.Main.Zoom = new Vector2(0.5f, 0.5f);
    }

    protected override void Process(float delta)
    {
        if (IsDie)
        {
            return;
        }
        base.Process(delta);
        //脸的朝向
        if (LookTarget == null)
        {
            var gPos = GlobalPosition;
            Vector2 mousePos = InputManager.CursorPosition;
            if (mousePos.X > gPos.X && Face == FaceDirection.Left)
            {
                Face = FaceDirection.Right;
            }
            else if (mousePos.X < gPos.X && Face == FaceDirection.Right)
            {
                Face = FaceDirection.Left;
            }
            //枪口跟随鼠标
            MountPoint.SetLookAt(mousePos);
        }

        if (InputManager.ExchangeWeapon) //切换武器
        {
            ExchangeNext();
        }
        else if (InputManager.ThrowWeapon) //扔掉武器
        {
            ThrowWeapon();

            // //测试用的, 所有敌人也扔掉武器
            // if (Affiliation != null)
            // {
            //     var enemies = Affiliation.FindIncludeItems(o =>
            //     {
            //         return o.CollisionWithMask(PhysicsLayer.Enemy);
            //     });
            //     foreach (var activityObject in enemies)
            //     {
            //         if (activityObject is Enemy enemy)
            //         {
            //             enemy.ThrowWeapon();
            //         }
            //     }
            // }
        }
        else if (InputManager.Interactive) //互动物体
        {
            TriggerInteractive();
        }
        else if (InputManager.Reload) //换弹
        {
            Reload();
        }
        if (InputManager.Fire) //开火
        {
            Attack();
        }

        if (InputManager.UseActiveProp) //使用道具
        {
            UseActiveProp();
        }

        if (Input.IsKeyPressed(Key.P))
        {
            Hurt(1000, 0);
        }
    }

    protected override void PhysicsProcess(float delta)
    {
        if (IsDie)
        {
            return;
        }

        base.PhysicsProcess(delta);
        HandleMoveInput(delta);
        //播放动画
        PlayAnim();
    }

    public override bool PickUpWeapon(Weapon weapon, bool exchange = true)
    {
        //拾起武器
        var result = base.PickUpWeapon(weapon, exchange);
        if (result)
        {
            EventManager.EmitEvent(EventEnum.OnPlayerPickUpWeapon, weapon);
        }
        return result;
    }

    public override void ThrowWeapon()
    {
        //扔掉武器
        var weapon = WeaponPack.ActiveItem;
        base.ThrowWeapon();
        EventManager.EmitEvent(EventEnum.OnPlayerRemoveWeapon, weapon);
    }

    public override void ThrowWeapon(int index)
    {
        //扔掉武器
        var weapon = WeaponPack.GetItem(index);
        base.ThrowWeapon(index);
        EventManager.EmitEvent(EventEnum.OnPlayerRemoveWeapon, weapon);
    }

    protected override int OnHandlerHurt(int damage)
    {
        //修改受到的伤害, 每次只受到1点伤害
        return 1;
    }

    protected override void OnHit(int damage, bool realHarm)
    {
        //进入无敌状态
        if (realHarm) //真实伤害
        {
            PlayInvincibleFlashing(RoleState.WoundedInvincibleTime);
        }
        else //护盾抵消掉的
        {
            PlayInvincibleFlashing(RoleState.ShieldInvincibleTime);
        }
    }

    protected override void OnChangeHp(int hp)
    {
        //GameApplication.Instance.Ui.SetHp(hp);
        EventManager.EmitEvent(EventEnum.OnPlayerHpChange, hp);
    }

    protected override void OnChangeMaxHp(int maxHp)
    {
        //GameApplication.Instance.Ui.SetMaxHp(maxHp);
        EventManager.EmitEvent(EventEnum.OnPlayerMaxHpChange, maxHp);
    }

    protected override void ChangeInteractiveItem(CheckInteractiveResult prev, CheckInteractiveResult result)
    {
        if (prev != null && prev.Target.ShowOutline)
        {
            prev.Target.OutlineColor = Colors.Black;
        }
        if (result != null && result.Target.ShowOutline)
        {
            result.Target.OutlineColor = Colors.White;
        }
        //派发互动对象改变事件
        EventManager.EmitEvent(EventEnum.OnPlayerChangeInteractiveItem, result);
    }

    protected override void OnChangeShield(int shield)
    {
        //GameApplication.Instance.Ui.SetShield(shield);
        EventManager.EmitEvent(EventEnum.OnPlayerShieldChange, shield);
    }

    protected override void OnChangeMaxShield(int maxShield)
    {
        //GameApplication.Instance.Ui.SetMaxShield(maxShield);
        EventManager.EmitEvent(EventEnum.OnPlayerMaxShieldChange, maxShield);
    }

    protected override void OnDie()
    {
        GameCamera.Main.SetFollowTarget(null);
        BasisVelocity = Vector2.Zero;
        MoveController.ClearForce();
        UiManager.Open_Settlement();
        //GameApplication.Instance.World.ProcessMode = ProcessModeEnum.WhenPaused;
    }

    protected override void OnPushProp(Prop prop)
    {
        EventManager.EmitEvent(EventEnum.OnPlayerPickUpProp, prop);
    }

    protected override void OnRemoveProp(Prop prop)
    {
        EventManager.EmitEvent(EventEnum.OnPlayerRemoveProp, prop);
    }

    //处理角色移动的输入
    private void HandleMoveInput(float delta)
    {
        //角色移动
        Vector2 dir = InputManager.MoveAxis;
        // 移动. 如果移动的数值接近0(是用 摇杆可能出现 方向 可能会出现浮点),就friction的值 插值 到 0
        // 如果 有输入 就以当前速度,用acceleration 插值到 对应方向 * 最大速度
        if (Mathf.IsZeroApprox(dir.X))
        {
            BasisVelocity = new Vector2(Mathf.MoveToward(BasisVelocity.X, 0, RoleState.Friction * delta), BasisVelocity.Y);
        }
        else
        {
            BasisVelocity = new Vector2(Mathf.MoveToward(BasisVelocity.X, dir.X * RoleState.MoveSpeed, RoleState.Acceleration * delta),
                BasisVelocity.Y);
        }

        if (Mathf.IsZeroApprox(dir.Y))
        {
            BasisVelocity = new Vector2(BasisVelocity.X, Mathf.MoveToward(BasisVelocity.Y, 0, RoleState.Friction * delta));
        }
        else
        {
            BasisVelocity = new Vector2(BasisVelocity.X,
                Mathf.MoveToward(BasisVelocity.Y, dir.Y * RoleState.MoveSpeed, RoleState.Acceleration * delta));
        }
    }

    // 播放动画
    private void PlayAnim()
    {
        if (BasisVelocity != Vector2.Zero)
        {
            if ((Face == FaceDirection.Right && BasisVelocity.X >= 0) || Face == FaceDirection.Left && BasisVelocity.X <= 0) //向前走
            {
                AnimatedSprite.Play(AnimatorNames.Run);
            }
            else if ((Face == FaceDirection.Right && BasisVelocity.X < 0) || Face == FaceDirection.Left && BasisVelocity.X > 0) //向后走
            {
                AnimatedSprite.Play(AnimatorNames.ReverseRun);
            }
        }
        else
        {
            AnimatedSprite.Play(AnimatorNames.Idle);
        }
    }
}