mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-07 21:25:53 +00:00
FSM Player health and animations
This commit is contained in:
parent
af0261ce8e
commit
f91df43caa
13 changed files with 317 additions and 32 deletions
|
|
@ -1,10 +1,19 @@
|
|||
using System.Threading.Tasks;
|
||||
using Cirno.Scripts;
|
||||
using Cirno.Scripts.Components;
|
||||
using Godot;
|
||||
using GTweens.Builders;
|
||||
using GTweens.Tweens;
|
||||
using GTweensGodot.Extensions;
|
||||
|
||||
public partial class PlayerAnimationProvider : Node2D
|
||||
{
|
||||
[Export]
|
||||
public AnimatedSprite2D _animatedSprite {get; private set;}
|
||||
|
||||
[Export] private PackedScene _deathParticles;
|
||||
[Export] private GpuParticles2D _shieldParticles;
|
||||
|
||||
[ExportCategory("Animation Names")]
|
||||
[Export]
|
||||
public string WalkRightAnimationName {get; private set;} = "walk_right";
|
||||
|
|
@ -16,6 +25,13 @@ public partial class PlayerAnimationProvider : Node2D
|
|||
[Export]
|
||||
public string WalkUpAnimationName {get; private set;} = "walk_up";
|
||||
|
||||
[ExportCategory("Shaders")]
|
||||
[Export] public ShaderMaterial BlinkMaterial {get; private set;}
|
||||
|
||||
[Export] public StringName BlinkShaderPropertyName { get; private set; } = new StringName("blink_intensity");
|
||||
|
||||
private GTween _blinkTween;
|
||||
|
||||
public void SetAnimation(Vector2 velocity)
|
||||
{
|
||||
if (velocity.X == 0 && velocity.Y == 0)
|
||||
|
|
@ -45,4 +61,46 @@ public partial class PlayerAnimationProvider : Node2D
|
|||
}
|
||||
}
|
||||
|
||||
public void Blink()
|
||||
{
|
||||
if (BlinkMaterial == null) return;
|
||||
_animatedSprite.Material = BlinkMaterial;
|
||||
|
||||
var material = ((ShaderMaterial)_animatedSprite.Material);
|
||||
|
||||
_blinkTween?.Kill();
|
||||
|
||||
_blinkTween = GTweenSequenceBuilder.New()
|
||||
.Append(material.TweenPropertyFloat(BlinkShaderPropertyName, 1f, 0f))
|
||||
.Append(material.TweenPropertyFloat(BlinkShaderPropertyName, 0f, 0.5f))
|
||||
.Build();
|
||||
|
||||
_blinkTween.Play();
|
||||
}
|
||||
|
||||
private void SetShaderTeleportProgress(float value)
|
||||
{
|
||||
((ShaderMaterial)_animatedSprite.Material).SetShaderParameter("teleport_progress", value);
|
||||
}
|
||||
|
||||
private void SetShaderScanlineDensity(float value)
|
||||
{
|
||||
((ShaderMaterial)_animatedSprite.Material).SetShaderParameter("scanline_density", value);
|
||||
}
|
||||
|
||||
private void SetShaderBlinkIntensity(float newValue)
|
||||
{
|
||||
((ShaderMaterial)_animatedSprite.Material).SetShaderParameter("blink_intensity", newValue);
|
||||
}
|
||||
|
||||
public void PlayDeathAnimation()
|
||||
{
|
||||
this.CreateSibling<AutodeleteParticle>(_deathParticles, this.GlobalPosition);
|
||||
_animatedSprite.Visible = false;
|
||||
}
|
||||
|
||||
public void PlayShieldAnimation()
|
||||
{
|
||||
_shieldParticles.Emitting = true;
|
||||
}
|
||||
}
|
||||
104
Scripts/Components/Actors/PlayerDamageReceiver.cs
Normal file
104
Scripts/Components/Actors/PlayerDamageReceiver.cs
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
using System;
|
||||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Components.Actors;
|
||||
|
||||
public partial class PlayerDamageReceiver : Area2D
|
||||
{
|
||||
[Export]
|
||||
public bool Enabled { get; set; } = false;
|
||||
[Export]
|
||||
public bool Invulnerable { get; private set; } = false;
|
||||
[Export] public BulletOwner BulletGroup { get; set; } = BulletOwner.Player;
|
||||
|
||||
[Export]
|
||||
private ActorResourceProvider _healthProvider;
|
||||
[Export]
|
||||
private ActorResourceProvider _shieldProvider;
|
||||
|
||||
[Signal]
|
||||
public delegate void HealthChangedEventHandler(float newValue, float maxValue);
|
||||
|
||||
[Signal]
|
||||
public delegate void ShieldChangedEventHandler(float newValue, float maxValue);
|
||||
|
||||
[Signal]
|
||||
public delegate void DeathEventHandler();
|
||||
|
||||
public float CurrentHealth
|
||||
{
|
||||
get => _healthProvider.CurrentResource;
|
||||
set => _healthProvider.CurrentResource = value;
|
||||
}
|
||||
|
||||
public float CurrentShield
|
||||
{
|
||||
get => _shieldProvider.CurrentResource;
|
||||
set => _shieldProvider.CurrentResource = value;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
_healthProvider.FillResource();
|
||||
_shieldProvider.FillResource();
|
||||
|
||||
_healthProvider.ResourceChanged += ((value, maxValue) =>
|
||||
{
|
||||
if (!Enabled) return;
|
||||
EmitSignal(SignalName.HealthChanged, value, maxValue);
|
||||
});
|
||||
|
||||
_shieldProvider.ResourceChanged += ((value, maxValue) =>
|
||||
{
|
||||
if (!Enabled) return;
|
||||
EmitSignal(SignalName.ShieldChanged, value, maxValue);
|
||||
});
|
||||
|
||||
_healthProvider.ResourceDepleted += () =>
|
||||
{
|
||||
if (!Enabled) return;
|
||||
EmitSignal(SignalName.Death);
|
||||
};
|
||||
}
|
||||
|
||||
private void _on_damage_hitbox_area_entered(Area2D area)
|
||||
{
|
||||
if (!Enabled) return;
|
||||
if (Invulnerable) return;
|
||||
if (area is not Bullet bullet || bullet.BulletOwner == BulletGroup) return;
|
||||
this.Hit(bullet.Damage, bullet.DamageType);
|
||||
bullet.RequestCollisionDestruction();
|
||||
}
|
||||
|
||||
public void Hit(float damage, DamageType type = DamageType.Neutral)
|
||||
{
|
||||
if (!Enabled) return;
|
||||
|
||||
if (CurrentShield > 0 && type is not DamageType.Explosive or DamageType.Acid)
|
||||
{
|
||||
// Reduce shield
|
||||
//PlayShieldAnimation(); // Let this be handled by event
|
||||
CurrentShield -= damage;
|
||||
if (CurrentShield < 0)
|
||||
{
|
||||
CurrentHealth -= Math.Abs(CurrentShield);
|
||||
CurrentShield = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type is DamageType.Fire)
|
||||
{
|
||||
CurrentHealth -= damage * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentHealth -= damage;
|
||||
}
|
||||
|
||||
//Blink(); // Let this be handled by event
|
||||
}
|
||||
|
||||
if (!(CurrentHealth <= 0)) return;
|
||||
}
|
||||
}
|
||||
1
Scripts/Components/Actors/PlayerDamageReceiver.cs.uid
Normal file
1
Scripts/Components/Actors/PlayerDamageReceiver.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dkmsw828qwikk
|
||||
|
|
@ -21,15 +21,15 @@ public partial class PlayerHitboxSpriteProvider : Node2D
|
|||
}
|
||||
}
|
||||
|
||||
public void Show()
|
||||
{
|
||||
Hitbox.Show();
|
||||
Circle.Show();
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
Hitbox.Hide();
|
||||
Circle.Hide();
|
||||
}
|
||||
// public void Show()
|
||||
// {
|
||||
// Hitbox.Show();
|
||||
// Circle.Show();
|
||||
// }
|
||||
//
|
||||
// public void Hide()
|
||||
// {
|
||||
// Hitbox.Hide();
|
||||
// Circle.Hide();
|
||||
// }
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ namespace Cirno.Scripts.Components.FSM.Player;
|
|||
public partial class Active : PlayerFSMState
|
||||
{
|
||||
private Vector2 _movementDirection { get; set; }
|
||||
public Vector2 FacingDirection { get; private set; }
|
||||
public Vector2 FacingDirection { get; private set; } = Vector2.Down;
|
||||
|
||||
[Export]
|
||||
public int Speed { get; set; } = 45;
|
||||
|
|
@ -27,16 +27,37 @@ public partial class Active : PlayerFSMState
|
|||
[Export]
|
||||
private InputProvider _inputProvider;
|
||||
|
||||
[Export] private PlayerDamageReceiver _damageReceiver;
|
||||
|
||||
private bool _isStrafing;
|
||||
|
||||
|
||||
|
||||
public int MovementSpeed => _isStrafing ? StrafeSpeed : Speed;
|
||||
|
||||
private PlayerStateMachine _player;
|
||||
|
||||
public override void Init(ActorStateMachine stateMachine)
|
||||
{
|
||||
base.Init(stateMachine);
|
||||
|
||||
_player = (PlayerStateMachine)stateMachine;
|
||||
|
||||
_damageReceiver.Death += () =>
|
||||
{
|
||||
ChangeState(PlayerState.Dead);
|
||||
};
|
||||
|
||||
_damageReceiver.HealthChanged += (value, maxValue) =>
|
||||
{
|
||||
_animationProvider.Blink();
|
||||
};
|
||||
|
||||
_damageReceiver.ShieldChanged += (value, maxValue) =>
|
||||
{
|
||||
_animationProvider.PlayShieldAnimation();
|
||||
};
|
||||
|
||||
_damageReceiver.Init();
|
||||
|
||||
//_weaponProvider = stateMachine.GetNode<PlayerWeaponProvider>("WeaponProvider");
|
||||
//_animationProvider = stateMachine.GetNode<PlayerAnimationProvider>("AnimationProvider");
|
||||
|
||||
|
|
@ -48,6 +69,8 @@ public partial class Active : PlayerFSMState
|
|||
// enable sprite
|
||||
// enable crosshair
|
||||
_crosshairProvider.Show();
|
||||
|
||||
_damageReceiver.Enabled = true;
|
||||
}
|
||||
|
||||
public override void ExitState()
|
||||
|
|
@ -55,6 +78,8 @@ public partial class Active : PlayerFSMState
|
|||
_animationProvider.SetAnimation(Vector2.Zero);
|
||||
_crosshairProvider.Hide();
|
||||
_hitboxSpriteProvider.Hide();
|
||||
|
||||
_damageReceiver.Enabled = false;
|
||||
}
|
||||
|
||||
public override void PhysicsProcessState(double delta)
|
||||
|
|
|
|||
29
Scripts/Components/FSM/Player/Dead.cs
Normal file
29
Scripts/Components/FSM/Player/Dead.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Components.FSM.Player;
|
||||
|
||||
public partial class Dead : PlayerFSMState
|
||||
{
|
||||
[Export]
|
||||
private PlayerAnimationProvider _animationProvider;
|
||||
|
||||
public override void EnterState()
|
||||
{
|
||||
_animationProvider.PlayDeathAnimation();
|
||||
}
|
||||
|
||||
public override void ExitState()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void ProcessState(double delta)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void PhysicsProcessState(double delta)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
1
Scripts/Components/FSM/Player/Dead.cs.uid
Normal file
1
Scripts/Components/FSM/Player/Dead.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bo6xcjnw3yn6s
|
||||
Loading…
Add table
Add a link
Reference in a new issue