diff --git a/Scenes/SettingsController.cs b/Scenes/SettingsController.cs index f4964df..76f84ac 100644 --- a/Scenes/SettingsController.cs +++ b/Scenes/SettingsController.cs @@ -14,10 +14,10 @@ public partial class SettingsController : VBoxContainer slRain = GetNode("weatherSettings/slRain"); slSize.ValueChanged += OnSizeValueChanged; - OnSizeValueChanged(main.BrushSize); + slSize.Value = main.BrushSize; slRain.ValueChanged += OnRainValueChanged; - OnRainValueChanged(main.RainAmount); + slRain.Value = main.RainAmount; } private void OnSizeValueChanged(double value) { diff --git a/Scenes/main.tscn b/Scenes/main.tscn index 6059423..e803dae 100644 --- a/Scenes/main.tscn +++ b/Scenes/main.tscn @@ -7,7 +7,8 @@ [node name="Main" type="Node2D"] script = ExtResource("1_k1i8e") BrushSize = 1 -RainAmount = 1.0 +TextureResolution = 0.25 +RainAmount = 0.0 [node name="CanvasLayer" type="CanvasLayer" parent="."] diff --git a/Scripts/Elements/Dirt.cs b/Scripts/Elements/Dirt.cs index 6900d64..a288c70 100644 --- a/Scripts/Elements/Dirt.cs +++ b/Scripts/Elements/Dirt.cs @@ -10,11 +10,4 @@ public class Dirt : Solid { DiffuseSpeed = 50; } - public override bool Update(int currentFrame) { - if (!base.Update(currentFrame)) return false; - - Tick(); - - return true; // not necessarily end, subclasses could do some more things - } } diff --git a/Scripts/Elements/Element.cs b/Scripts/Elements/Element.cs index 9a3cd00..254eed4 100644 --- a/Scripts/Elements/Element.cs +++ b/Scripts/Elements/Element.cs @@ -7,15 +7,19 @@ public class Element { public Vector2I Position; public int Density; + public int LastUpdate = -1; + public int LastMove = 0; public int DiffuseSpeed = 10; public const int MAX_DIFFUSE_SPEED = 100; + public const int STEPS_UNTIL_INACTIVE = 100; protected const float MAX_COLOR_VARIANCE = 0.1f; protected static readonly Vector2I VERTICAL_OPPOSITE = new Vector2I(-1, 1); protected readonly Level Level; - private int lastUpdate = -1; + private bool active = true; + private Color originalColor; public Element(Element e) { Position = e.Position; @@ -28,14 +32,28 @@ public class Element { Level = level; } + public bool Active { + get => active; + set { + active = value; + + if (active) + Color = originalColor; + else if (Main.Instance.DebugVisualization) + Color = new Color(0.2f, 0.2f, 0.2f); + } + } + /// /// base update method, checks if anything is to do at all /// /// /// false if there is nothing to do public virtual bool Update(int currentFrame) { - if (lastUpdate == currentFrame) return false; // already updated this frame - lastUpdate = currentFrame; + if (!Active) return false; + + if (LastUpdate == currentFrame) return false; // already updated this frame + LastUpdate = currentFrame; return true; } @@ -74,6 +92,8 @@ public class Element { c.R += (GD.Randf() - 1) * MAX_COLOR_VARIANCE; c.G += (GD.Randf() - 1) * MAX_COLOR_VARIANCE; c.B += (GD.Randf() - 1) * MAX_COLOR_VARIANCE; + + originalColor = c; return c; } diff --git a/Scripts/Elements/Liquid.cs b/Scripts/Elements/Liquid.cs index b581f16..c330c7f 100644 --- a/Scripts/Elements/Liquid.cs +++ b/Scripts/Elements/Liquid.cs @@ -1,9 +1,33 @@ -using System; -using Godot; +using Godot; namespace FOU.Scripts.Elements; public abstract class Liquid : Element { + public const int MAX_VERTICAL_SPREAD = 3; + protected Liquid(int x, int y, ref Level level) : base(x, y, level) { } + public override bool Update(int currentFrame) { + if (!base.Update(currentFrame)) return false; + if (LastMove + STEPS_UNTIL_INACTIVE < currentFrame) Active = false; + + Tick(); + + return true; // not necessarily end, subclasses could do some more things + } + + protected override void Tick() { + Vector2I randomDirection = RandomDirectionDown(); + if (randomDirection.Y != 0) + randomDirection *= Vector2I.Left * (int)(GD.Randi() % MAX_VERTICAL_SPREAD); + + if (Level.IsEmpty(Position + Vector2I.Down)) + Level.Swap(this, Position + Vector2I.Down); + + else if (Level.IsEmpty(Position + randomDirection)) + Level.Swap(this, Position + Vector2I.Right * randomDirection); + + else if (Level.IsEmpty(Position + randomDirection)) + Level.Swap(this, Position + Vector2I.Right * randomDirection * VERTICAL_OPPOSITE); + } } diff --git a/Scripts/Elements/Solid.cs b/Scripts/Elements/Solid.cs index 97bb1fe..9ad4913 100644 --- a/Scripts/Elements/Solid.cs +++ b/Scripts/Elements/Solid.cs @@ -5,4 +5,12 @@ namespace FOU.Scripts.Elements; public abstract class Solid : Element { protected Solid(int x, int y, ref Level level) : base(x, y, level) { } + public override bool Update(int currentFrame) { + if (!base.Update(currentFrame)) return false; + if (LastMove + STEPS_UNTIL_INACTIVE < currentFrame) Active = false; + + Tick(); + + return true; // not necessarily end, subclasses could do some more things + } } diff --git a/Scripts/Elements/Water.cs b/Scripts/Elements/Water.cs index 566d2c3..71cbcf4 100644 --- a/Scripts/Elements/Water.cs +++ b/Scripts/Elements/Water.cs @@ -2,34 +2,11 @@ namespace FOU.Scripts.Elements; -public class Water : Solid { - public const int MAX_VERTICAL_SPREAD = 3; +public class Water : Liquid { public Water(int x, int y, ref Level level) : base(x, y, ref level) { Color = AddColorVariance(Colors.Blue); Density = 1; } - public override bool Update(int currentFrame) { - if (!base.Update(currentFrame)) return false; - - Tick(); - - return true; // not necessarily end, subclasses could do some more things - } - - protected override void Tick() { - Vector2I randomDirection = RandomDirectionDown(); - if (randomDirection.Y != 0) - randomDirection *= Vector2I.Left * (int)(GD.Randi() % MAX_VERTICAL_SPREAD); - - if (Level.IsEmpty(Position + Vector2I.Down)) - Level.Swap(this, Position + Vector2I.Down); - - else if (Level.IsEmpty(Position + randomDirection)) - Level.Swap(this, Position + Vector2I.Right * randomDirection); - - else if (Level.IsEmpty(Position + randomDirection)) - Level.Swap(this, Position + Vector2I.Right * randomDirection * VERTICAL_OPPOSITE); - } } diff --git a/Scripts/Level.cs b/Scripts/Level.cs index 667a140..f2b740d 100644 --- a/Scripts/Level.cs +++ b/Scripts/Level.cs @@ -61,7 +61,8 @@ public class Level { int Y = Mathf.Clamp(y + j, 0, SizeY-1); object o = Activator.CreateInstance(type, X, Y, _this); - _elements[X,Y] = o as Element; + if (_elements[X,Y].GetType() != type) + _elements[X,Y] = o as Element; } } } @@ -75,7 +76,7 @@ public class Level { return mImage; } - public void Swap(Element what, Element swapTo) { + private void Swap(Element what, Element swapTo) { Element swap = new Element(what); if (what == null || swapTo == null) return; @@ -85,6 +86,11 @@ public class Level { swapTo.Position = swap.Position; _elements[swap.Position.X, swap.Position.Y] = swapTo; + + what.Active = true; + swapTo.Active = true; + what.LastMove = _frame; + swapTo.LastMove = _frame; } public void Swap(Element what, Vector2I pos) { diff --git a/Scripts/Main.cs b/Scripts/Main.cs index 8132101..732c10a 100644 --- a/Scripts/Main.cs +++ b/Scripts/Main.cs @@ -3,10 +3,14 @@ using FOU.Scripts.Elements; using Godot; public partial class Main : Node2D { + [Export] public bool DebugVisualization = false; + [Export] public int BrushSize = 5; [Export] public float TextureResolution = 0.5f; [Export] public float RainAmount = 0.01f; + public static Main Instance; + private TextureRect mLevelDrawer; private Level mLevel; @@ -15,6 +19,8 @@ public partial class Main : Node2D { (int)(GetViewportRect().Size.Y * TextureResolution), this ); mLevelDrawer = GetNode("CanvasLayer/LevelDrawer"); + + Instance = this; } public override void _Process(double delta) {