Compare commits
2 Commits
99473d1295
...
54ffa8a42c
Author | SHA1 | Date | |
---|---|---|---|
54ffa8a42c | |||
ac477115c5 |
42
scripts/components/EnemyDeathComponent.cs
Normal file
42
scripts/components/EnemyDeathComponent.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System.Threading.Tasks;
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
public partial class EnemyDeathComponent : Node
|
||||
{
|
||||
[Export] public float TweenDuration { get; set; } = 0.5f;
|
||||
[Export] public CollisionShape2D CollisionShape { get; set; }
|
||||
[Export] public HealthComponent Health { get; set; }
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (CollisionShape == null)
|
||||
{
|
||||
GD.PushError("EnemyDeathComponent: CollisionShape is not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Health == null)
|
||||
{
|
||||
GD.PushError("EnemyDeathComponent: Health is not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
Health.Death += OnDeath;
|
||||
}
|
||||
|
||||
private void OnDeath()
|
||||
{
|
||||
CallDeferred(nameof(Die));
|
||||
}
|
||||
|
||||
private async Task Die()
|
||||
{
|
||||
CollisionShape.SetDisabled(true);
|
||||
var tween = CreateTween();
|
||||
tween.TweenProperty(Owner, "scale", Vector2.Zero, TweenDuration);
|
||||
await ToSignal(tween, Tween.SignalName.Finished);
|
||||
Owner.QueueFree();
|
||||
}
|
||||
}
|
51
scripts/components/EnemyWaveTriggerComponent.cs
Normal file
51
scripts/components/EnemyWaveTriggerComponent.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
public partial class EnemyWaveTriggerComponent : Node
|
||||
{
|
||||
[Export] public Area2D Area2D { get; set; }
|
||||
[Export] public PathFollow2D PathFollowNode { get; set; }
|
||||
[Export] public float Speed { get; set; } = 100f;
|
||||
[Export] public bool Loop { get; set; } = false;
|
||||
[Export] public bool ActivateOnEnter { get; set; } = true;
|
||||
|
||||
private bool _isActive = false;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
Area2D.BodyEntered += OnBodyEntered;
|
||||
|
||||
if (PathFollowNode == null) return;
|
||||
|
||||
PathFollowNode.SetProgress(0f);
|
||||
PathFollowNode.SetProcess(false);
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (!_isActive || PathFollowNode == null) return;
|
||||
|
||||
var progress = PathFollowNode.Progress;
|
||||
progress += (float)(delta * Speed);
|
||||
PathFollowNode.SetProgress(progress);
|
||||
|
||||
if (!(PathFollowNode.ProgressRatio >= 1f) || Loop) return;
|
||||
|
||||
_isActive = false;
|
||||
PathFollowNode.SetProcess(false);
|
||||
}
|
||||
|
||||
private void OnBodyEntered(Node2D body)
|
||||
{
|
||||
if (ActivateOnEnter) StartWave();
|
||||
}
|
||||
|
||||
private void StartWave()
|
||||
{
|
||||
if (PathFollowNode == null) return;
|
||||
|
||||
PathFollowNode.SetProcess(true);
|
||||
_isActive = true;
|
||||
}
|
||||
}
|
51
scripts/components/ExitDoorComponent.cs
Normal file
51
scripts/components/ExitDoorComponent.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
public partial class ExitDoorComponent : Node
|
||||
{
|
||||
[Export] public bool Locked { get; set; } = true;
|
||||
[Export] public Area2D ExitArea { get; set; }
|
||||
[Export] public Sprite2D DoorSprite { get; set; }
|
||||
[Export] public AudioStreamPlayer2D OpenDoorSfx { get; set; }
|
||||
[Export] public int OpenedDoorFrame { get; set; } = 0;
|
||||
|
||||
[Signal] public delegate void ExitTriggeredEventHandler();
|
||||
|
||||
private GameManager _gameManager;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (ExitArea == null)
|
||||
{
|
||||
GD.PushError("ExitDoorComponent: ExitArea is not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
ExitArea.BodyEntered += OnExitAreaBodyEntered;
|
||||
|
||||
_gameManager = GetNode<GameManager>("/root/gameManager");
|
||||
}
|
||||
|
||||
private void OnExitAreaBodyEntered(Node2D body)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
private void Unlock()
|
||||
{
|
||||
Locked = false;
|
||||
if (DoorSprite != null)
|
||||
{
|
||||
DoorSprite.Frame = OpenedDoorFrame;
|
||||
}
|
||||
|
||||
OpenDoorSfx?.Play();
|
||||
}
|
||||
|
||||
private void GoToNextLevel()
|
||||
{
|
||||
_gameManager.OnLevelComplete();
|
||||
}
|
||||
}
|
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 _fallGravity;
|
||||
|
||||
public Vector2 LastDirection => _lastDirection;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
|
Reference in New Issue
Block a user