Add new components: ExplosiveComponent, FadeAwayComponent, FireEffectComponent, FlipComponent, GravityMotionComponent, LaunchComponent, and update PlatformMovement with LastDirection property
This commit is contained in:
81
scripts/components/ExplosiveComponent.cs
Normal file
81
scripts/components/ExplosiveComponent.cs
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Mr.BrickAdventures.scripts.components;
|
||||||
|
|
||||||
|
public partial class ExplosiveComponent : Node2D
|
||||||
|
{
|
||||||
|
[Export] public DamageComponent Damage { get; set; }
|
||||||
|
[Export] public Area2D Area { get; set; }
|
||||||
|
[Export] public Area2D ExplodeArea { get; set; }
|
||||||
|
[Export] public PackedScene ExplosionEffect { get; set; }
|
||||||
|
[Export] public float TimeToExplode { get; set; } = 9f;
|
||||||
|
|
||||||
|
[Signal] public delegate void OnExplosionEventHandler(Node2D body);
|
||||||
|
|
||||||
|
private Timer _timer;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
if (Damage != null)
|
||||||
|
{
|
||||||
|
GD.PushError("ExplosiveComponent: DamageComponent is not set.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ExplodeArea != null)
|
||||||
|
{
|
||||||
|
GD.PushError("ExplosiveComponent: ExplodeArea is not set.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Area.BodyEntered += OnAreaBodyEntered;
|
||||||
|
Area.AreaEntered += OnAreaAreaEntered;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAreaAreaEntered(Area2D area)
|
||||||
|
{
|
||||||
|
Explode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAreaBodyEntered(Node2D body)
|
||||||
|
{
|
||||||
|
Explode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrepareTimer()
|
||||||
|
{
|
||||||
|
_timer = new Timer();
|
||||||
|
_timer.SetWaitTime(TimeToExplode);
|
||||||
|
_timer.OneShot = true;
|
||||||
|
_timer.Autostart = true;
|
||||||
|
_timer.Timeout += Explode;
|
||||||
|
AddChild(_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Explode()
|
||||||
|
{
|
||||||
|
_timer.Stop();
|
||||||
|
|
||||||
|
if (ExplosionEffect != null)
|
||||||
|
{
|
||||||
|
var explosionInstance = ExplosionEffect.Instantiate<GpuParticles2D>();
|
||||||
|
if (Owner is Node2D root) explosionInstance.SetGlobalPosition(root.GlobalPosition);
|
||||||
|
GetTree().CurrentScene.AddChild(explosionInstance);
|
||||||
|
explosionInstance.SetEmitting(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
var bodies = ExplodeArea.GetOverlappingBodies();
|
||||||
|
foreach (var body in bodies)
|
||||||
|
{
|
||||||
|
var health = body.GetNodeOrNull<HealthComponent>("HealthComponent");
|
||||||
|
if (Damage != null && health != null)
|
||||||
|
{
|
||||||
|
Damage.DealDamage(health);
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitSignalOnExplosion(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
Owner.QueueFree();
|
||||||
|
}
|
||||||
|
}
|
32
scripts/components/FadeAwayComponent.cs
Normal file
32
scripts/components/FadeAwayComponent.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Mr.BrickAdventures.scripts.components;
|
||||||
|
|
||||||
|
public partial class FadeAwayComponent : Node
|
||||||
|
{
|
||||||
|
[Export] public Sprite2D Sprite { get; set; }
|
||||||
|
[Export] public float FadeDuration { get; set; } = 1f;
|
||||||
|
[Export] public float Speed { get; set; } = 10f;
|
||||||
|
[Export] public Vector2 Direction { get; set; } = Vector2.Up;
|
||||||
|
[Export] public Area2D Area { get; set; }
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
Area.BodyEntered += OnBodyEntered;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBodyEntered(Node2D body)
|
||||||
|
{
|
||||||
|
_ = FadeAway();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task FadeAway()
|
||||||
|
{
|
||||||
|
var tween = CreateTween().SetParallel(true);
|
||||||
|
tween.TweenProperty(Sprite, "modulate:a", 0f, FadeDuration);
|
||||||
|
tween.TweenProperty(Sprite, "position", Sprite.Position + (Direction * Speed), FadeDuration);
|
||||||
|
await ToSignal(tween, Tween.SignalName.Finished);
|
||||||
|
Owner.QueueFree();
|
||||||
|
}
|
||||||
|
}
|
71
scripts/components/FireEffectComponent.cs
Normal file
71
scripts/components/FireEffectComponent.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using Godot;
|
||||||
|
using Mr.BrickAdventures.scripts.Resources;
|
||||||
|
|
||||||
|
namespace Mr.BrickAdventures.scripts.components;
|
||||||
|
|
||||||
|
public partial class FireEffectComponent : Node
|
||||||
|
{
|
||||||
|
[Export] public HealthComponent Health { get; set; }
|
||||||
|
[Export] public StatusEffectComponent StatusEffectComponent { get; set; }
|
||||||
|
[Export] public GpuParticles2D FireFX { get; set; }
|
||||||
|
|
||||||
|
private StatusEffectDataResource _data = null;
|
||||||
|
private bool _shouldDealDamage = false;
|
||||||
|
private double _timeElapsed = 0f;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
if (Health == null)
|
||||||
|
{
|
||||||
|
Health = GetNode<HealthComponent>("HealthComponent");
|
||||||
|
}
|
||||||
|
if (StatusEffectComponent == null)
|
||||||
|
{
|
||||||
|
StatusEffectComponent = GetNode<StatusEffectComponent>("StatusEffectComponent");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Health == null)
|
||||||
|
{
|
||||||
|
GD.PushError("FireEffectComponent: HealthComponent is not set.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (StatusEffectComponent == null)
|
||||||
|
{
|
||||||
|
GD.PushError("FireEffectComponent: StatusEffectComponent is not set.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusEffectComponent.EffectApplied += OnEffectApplied;
|
||||||
|
StatusEffectComponent.EffectRemoved += OnEffectRemoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Process(double delta)
|
||||||
|
{
|
||||||
|
if (!_shouldDealDamage || _data == null || Health == null) return;
|
||||||
|
|
||||||
|
_timeElapsed += delta;
|
||||||
|
if (_timeElapsed >= 1f)
|
||||||
|
{
|
||||||
|
Health.DecreaseHealth(_data.DamagePerSecond);
|
||||||
|
_timeElapsed = 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEffectApplied(StatusEffect statusEffect)
|
||||||
|
{
|
||||||
|
if (statusEffect.EffectData.Type != StatusEffectType.Fire) return;
|
||||||
|
|
||||||
|
_data = statusEffect.EffectData;
|
||||||
|
_shouldDealDamage = true;
|
||||||
|
FireFX?.SetEmitting(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEffectRemoved(StatusEffectType type)
|
||||||
|
{
|
||||||
|
if (type != StatusEffectType.Fire) return;
|
||||||
|
|
||||||
|
_shouldDealDamage = false;
|
||||||
|
_data = null;
|
||||||
|
FireFX?.SetEmitting(false);
|
||||||
|
}
|
||||||
|
}
|
36
scripts/components/FlipComponent.cs
Normal file
36
scripts/components/FlipComponent.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Mr.BrickAdventures.scripts.components;
|
||||||
|
|
||||||
|
public partial class FlipComponent : Node2D
|
||||||
|
{
|
||||||
|
[Export] public Sprite2D LeftEye { get; set; }
|
||||||
|
[Export] public Sprite2D RightEye { get; set; }
|
||||||
|
[Export] public PlatformMovement PlatformMovement { get; set; }
|
||||||
|
|
||||||
|
public override void _Process(double delta)
|
||||||
|
{
|
||||||
|
if (PlatformMovement == null) return;
|
||||||
|
|
||||||
|
var velocity = PlatformMovement.LastDirection;
|
||||||
|
switch (velocity.X)
|
||||||
|
{
|
||||||
|
case < 0f:
|
||||||
|
LeftEye.Frame = 1;
|
||||||
|
RightEye.Frame = 1;
|
||||||
|
LeftEye.FlipH = true;
|
||||||
|
RightEye.FlipH = true;
|
||||||
|
break;
|
||||||
|
case > 0f:
|
||||||
|
LeftEye.Frame = 1;
|
||||||
|
RightEye.Frame = 1;
|
||||||
|
LeftEye.FlipH = false;
|
||||||
|
RightEye.FlipH = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LeftEye.Frame = 0;
|
||||||
|
RightEye.Frame = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
scripts/components/GravityMotionComponent.cs
Normal file
37
scripts/components/GravityMotionComponent.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Mr.BrickAdventures.scripts.components;
|
||||||
|
|
||||||
|
public partial class GravityMotionComponent : Node2D
|
||||||
|
{
|
||||||
|
[Export] public CharacterBody2D Body { get; set; }
|
||||||
|
[Export] public LaunchComponent LaunchComponent { get; set; }
|
||||||
|
[Export] public Vector2 Gravity { get; set; } = new Vector2(0, 1000f);
|
||||||
|
[Export] public Vector2 TargetDirection { get; set; } = Vector2.Up;
|
||||||
|
|
||||||
|
private Vector2 _velocity = Vector2.Zero;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
if (LaunchComponent == null) return;
|
||||||
|
|
||||||
|
var direction = LaunchComponent.InitialDirection.X > 0f ? TargetDirection : new Vector2(-TargetDirection.X, TargetDirection.Y);
|
||||||
|
direction = direction.Normalized();
|
||||||
|
_velocity = direction * LaunchComponent.Speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _PhysicsProcess(double delta)
|
||||||
|
{
|
||||||
|
if (Body == null) return;
|
||||||
|
|
||||||
|
_velocity += Gravity * (float)delta;
|
||||||
|
Body.Velocity = _velocity;
|
||||||
|
|
||||||
|
Body.MoveAndSlide();
|
||||||
|
|
||||||
|
if (_velocity.LengthSquared() > 0.01f)
|
||||||
|
{
|
||||||
|
Body.Rotation = _velocity.Angle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
scripts/components/LaunchComponent.cs
Normal file
24
scripts/components/LaunchComponent.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Mr.BrickAdventures.scripts.components;
|
||||||
|
|
||||||
|
public partial class LaunchComponent : Node2D
|
||||||
|
{
|
||||||
|
[Export] public Vector2 InitialDirection { get; set; } = Vector2.Right;
|
||||||
|
[Export] public float Speed { get; set; } = 16f;
|
||||||
|
[Export] public Vector2 SpawnPosition { get; set; } = Vector2.Zero;
|
||||||
|
[Export] public float SpawnRotation { get; set; } = 0f;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
if (Owner is not Node2D root) return;
|
||||||
|
|
||||||
|
root.GlobalPosition = SpawnPosition;
|
||||||
|
root.GlobalRotation = SpawnRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 GetInitialVelocity()
|
||||||
|
{
|
||||||
|
return InitialDirection.Normalized() * Speed;
|
||||||
|
}
|
||||||
|
}
|
@@ -39,6 +39,8 @@ public partial class PlatformMovement : Node2D, IMovement
|
|||||||
private float _jumpGravity;
|
private float _jumpGravity;
|
||||||
private float _fallGravity;
|
private float _fallGravity;
|
||||||
|
|
||||||
|
public Vector2 LastDirection => _lastDirection;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
base._Ready();
|
base._Ready();
|
||||||
|
Reference in New Issue
Block a user