FSM Player health and animations

This commit is contained in:
Marco 2025-03-01 14:08:31 +01:00
commit f91df43caa
13 changed files with 317 additions and 32 deletions

View file

@ -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;
}
}

View 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;
}
}

View file

@ -0,0 +1 @@
uid://dkmsw828qwikk

View file

@ -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();
// }
}