Particles system

This commit is contained in:
Rendo 2025-06-28 02:44:42 +05:00
commit 0e5dee50f7
46 changed files with 643 additions and 200 deletions

View file

@ -1,4 +1,5 @@
using Godot;
using Newlon.Components.Level;
using Newlon.Systems.Effects;
namespace Newlon.Components;
@ -17,6 +18,8 @@ public partial class LinearProjectile : Area2D, IProjectile
private Effect _impactEffect;
[Export]
private Utility.DamageTypes _damageType = Utility.DamageTypes.PHYSICAL;
[Export]
private PackedScene particles;
private int _line;
private bool used = false;
public int Line { get => _line; set { _line = value; } }
@ -37,6 +40,9 @@ public partial class LinearProjectile : Area2D, IProjectile
used = true;
if (entity is IEffectHandler effectHandler && _impactEffect != null)
effectHandler.GiveEffect(_impactEffect);
PoolContainer.Instance.SpawnParticles(particles, GlobalPosition);
QueueFree();
}
}

View file

@ -11,7 +11,7 @@ public partial class PauseMenu : Control
public void Continue()
{
Visible = false;
GetParent<Control>().Visible = false;
GetTree().Paused = false;
}
public void Restart()
@ -26,7 +26,7 @@ public partial class PauseMenu : Control
}
public static void Pause()
{
Instance.Visible = true;
Instance.GetParent<Control>().Visible = true;
Instance.GetTree().Paused = true;
}
}

View file

@ -6,6 +6,7 @@ namespace Newlon.Components.GUI;
public partial class ShovelButton : TextureButton
{
[Export] private PackedScene particles;
private void OnFocusExited()
{
ButtonPressed = false;
@ -27,7 +28,10 @@ public partial class ShovelButton : TextureButton
{
if (PoolContainer.Instance.EntityField[i].TryGetValue(checkedPosition, out var entity) && entity is RuntimePlantData plantData)
{
plantData.Kill();
plantData.Kill();
PoolContainer.Instance.SpawnParticles(particles, plantData.GlobalPosition + Vector2.Down * Utility.TileHeight/2.0f);
break;
}
}

View file

@ -10,7 +10,7 @@ public partial class PlantField : Node2D
private PlantResource _resource;
private Seedpacket _slot;
private bool _previousCanPlace;
[Export] private PackedScene particles;
public static PlantField Instance {get; private set;}
public override void _Ready()
@ -97,6 +97,8 @@ public partial class PlantField : Node2D
RuntimeLevelData.Instance.SpendSun(_resource.Cost);
PoolContainer.Instance.SpawnParticles(particles, plant.GlobalPosition + Vector2.Down * Utility.TileHeight/2.0f);
// Unfocusing and recharging slot
_slot.Recharge();
}

View file

@ -18,8 +18,10 @@ public partial class PoolContainer : Node2D
public Node2D Projectiles { get; private set; }
[Export]
public Node2D Structures { get; private set; }
[Export]
public Node2D Particles { get; private set; }
public static PoolContainer Instance {get; private set;}
public static PoolContainer Instance { get; private set; }
public Dictionary<Vector2, IEntity>[] EntityField = { new(), new(), new() };
public override void _Ready()
@ -27,31 +29,38 @@ public partial class PoolContainer : Node2D
Instance = this;
}
public bool TryGetEntity(Vector2 key, out IEntity result, int layer = 1)
{
if (EntityField[layer].ContainsKey(key))
{
result = EntityField[layer][key];
}
else
{
result = null;
}
return EntityField[layer].ContainsKey(key)
{
if (EntityField[layer].ContainsKey(key))
{
result = EntityField[layer][key];
}
else
{
result = null;
}
return EntityField[layer].ContainsKey(key)
&& EntityField[layer][key] != null;
}
}
public bool TryGetEntity<T>(Vector2 key, out T result, int layer = 1) where T : class
{
if (EntityField[layer].ContainsKey(key))
{
result = EntityField[layer][key] as T;
}
else
{
result = null;
}
return EntityField[layer].ContainsKey(key)
{
result = EntityField[layer][key] as T;
}
else
{
result = null;
}
return EntityField[layer].ContainsKey(key)
&& EntityField[layer][key] != null
&& result != null;
}
public void SpawnParticles(PackedScene particles, Vector2 position)
{
var emitter = particles.Instantiate<StandardParticles>();
Instance.Particles.AddChild(emitter);
emitter.GlobalPosition = position;
}
}

View file

@ -0,0 +1,22 @@
using Godot;
public partial class StandardParticles : Node2D
{
private int counter = 0;
private int counterMax = 0;
public override void _Ready()
{
foreach (GpuParticles2D emitter in GetChildren())
{
emitter.Emitting = true;
counterMax += 1;
emitter.Finished += MarkForDestruction;
}
}
public void MarkForDestruction()
{
if (Engine.IsEditorHint()) return;
if (++counter < counterMax) return;
QueueFree();
}
}

View file

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

View file

@ -1,4 +1,5 @@
using Godot;
using Newlon.Components.Level;
using Newlon.Components.Zombies;
namespace Newlon.Components.Plants;
@ -6,15 +7,19 @@ namespace Newlon.Components.Plants;
public partial class ExplosionComponent : Area2D
{
[Export] private int damage;
[Export] private PackedScene particles;
public void Explode()
{
foreach(var zombie in GetOverlappingAreas())
foreach (var zombie in GetOverlappingAreas())
{
var zombieData = zombie.GetParent<RuntimeZombieData>();
zombieData?.TakeDamage(damage,GetParent());
zombieData?.TakeDamage(damage, GetParent());
}
PoolContainer.Instance.SpawnParticles(particles, GetParent<RuntimePlantData>().GlobalPosition);
GetParent<RuntimePlantData>().Kill();
}
}