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 _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