diff --git a/Scenes/main.tscn b/Scenes/main.tscn index 0c4b008..46fcbc7 100644 --- a/Scenes/main.tscn +++ b/Scenes/main.tscn @@ -4,9 +4,9 @@ [node name="Main" type="Node2D"] script = ExtResource("1_k1i8e") -BrushSize = 3 +BrushSize = 1 TextureResolution = 0.25 -RainAmount = 0.15 +RainAmount = 1.0 [node name="CanvasLayer" type="CanvasLayer" parent="."] diff --git a/Scripts/Elements/Dirt.cs b/Scripts/Elements/Dirt.cs index 1a90177..ad829db 100644 --- a/Scripts/Elements/Dirt.cs +++ b/Scripts/Elements/Dirt.cs @@ -12,14 +12,8 @@ public class Dirt : Solid { public override bool Update(int currentFrame) { if (!base.Update(currentFrame)) return false; - Vector2I freePos = Check(this, Vector2I.Down + Vector2I.Right); - - if (freePos != Vector2I.Zero) { // diagonally right - Level.Swap(this, freePos); - return true; - } + 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 29bcdf9..8d9f886 100644 --- a/Scripts/Elements/Element.cs +++ b/Scripts/Elements/Element.cs @@ -12,6 +12,11 @@ public class Element { private int lastUpdate = -1; + public Element(Element e) { + Position = e.Position; + Level = e.Level; + } + public Element(int x, int y, Level level) { Position.X = x; Position.Y = y; @@ -34,24 +39,20 @@ public class Element { return $"{GetType()} {Position}"; } - // OBSOLETE: - // protected bool CheckBelow(int sourceX, int sourceY) { - // if (sourceY+1 >= _level.SizeY) return false; - // - // if (_level.Get(sourceX, sourceY+1).GetType() == GetType()) - // return false; - // - // return true; - // } + protected virtual void Tick() { + int randomDirection = 1; + if (GD.Randi() % 2 != 0) + randomDirection *= -1; - /// - /// Checks from source to maxDirection (also X-mirrored) and returns a free position - /// - /// from where to check - /// where to go to (max). X is treated as [-X..X] - /// free position or V2.zero if nothing was found - protected virtual Vector2I Check(Element source, Vector2I maxDirection) { - return Vector2I.Zero; + if (Level.IsEmpty(Position + Vector2I.Down)) { + Level.Swap(this, Position + Vector2I.Down); + + } else if (Level.IsEmpty(Position + Vector2I.Down + Vector2I.Right * randomDirection)) { + Level.Swap(this, Position + Vector2I.Right * randomDirection); + + } else if (Level.IsEmpty(Position + Vector2I.Down + Vector2I.Right * randomDirection * -1)) { + Level.Swap(this, Position + Vector2I.Right*randomDirection); + } } protected Color AddColorVariance(Color baseColor) { diff --git a/Scripts/Elements/Liquid.cs b/Scripts/Elements/Liquid.cs index 302442f..b581f16 100644 --- a/Scripts/Elements/Liquid.cs +++ b/Scripts/Elements/Liquid.cs @@ -1,39 +1,9 @@ -using Godot; +using System; +using Godot; namespace FOU.Scripts.Elements; public abstract class Liquid : Element { protected Liquid(int x, int y, ref Level level) : base(x, y, level) { } - - // TODO: rework this! - protected override Vector2I Check(Element source, Vector2I maxDirection) { - if (GD.Randi() % 2 != 0) - maxDirection.X *= -1; - - Vector2I freePos = Vector2I.Zero; - for (int y = maxDirection.Y; y > 0; y--) { // height - if (source.Position.Y + y >= Level.SizeY) return freePos; // bounds check - - // check if we can further - if (Level.Get(source.Position.X, source.Position.Y + y).GetType() == typeof(Element)) { - freePos = new Vector2I(source.Position.X, source.Position.Y + y); - } else { - freePos = Vector2I.Zero; - } - - for (int x = -maxDirection.X; x <= maxDirection.X; x++) { // width - if (freePos != Vector2I.Zero) break; - - if (source.Position.X + x >= Level.SizeX || source.Position.X + x < 0) continue; // bounds check - - if (Level.Get(source.Position.X + x, source.Position.Y + y).GetType() == typeof(Element)) { - freePos = new Vector2I(source.Position.X + x, source.Position.Y + y); - break; - } - } - } - - return freePos; - } } diff --git a/Scripts/Elements/Snow.cs b/Scripts/Elements/Snow.cs deleted file mode 100644 index 0345400..0000000 --- a/Scripts/Elements/Snow.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Godot; - -namespace FOU.Scripts.Elements; - -public class Snow : Solid { - public Snow(int x, int y, ref Level level) : base(x, y, ref level) { - Color = Colors.White; - Color = AddColorVariance(Color); - } - - public override bool Update(int currentFrame) { - if (!base.Update(currentFrame)) return false; - - Vector2I freePos = Check(this, Vector2I.Down); - - if (freePos != Vector2I.Zero) { // diagonally right - Level.Swap(this, freePos); - return true; - } - - return true; // not necessarily end, subclasses could do some more things - } -} diff --git a/Scripts/Elements/Solid.cs b/Scripts/Elements/Solid.cs index 4627bb3..97bb1fe 100644 --- a/Scripts/Elements/Solid.cs +++ b/Scripts/Elements/Solid.cs @@ -5,32 +5,4 @@ namespace FOU.Scripts.Elements; public abstract class Solid : Element { protected Solid(int x, int y, ref Level level) : base(x, y, level) { } - protected Vector2I Check(Element source, Vector2I maxDirection) { - if (GD.Randi() % 2 != 0) - maxDirection.X *= -1; - - Vector2I freePos = Vector2I.Zero; - for (int y = maxDirection.Y; y > 0; y--) { // height - if (source.Position.Y + y >= Level.SizeY) return freePos; // bounds check - - if (Level.Get(source.Position.X, source.Position.Y + y).GetType() == typeof(Element)) { - freePos = new Vector2I(source.Position.X, source.Position.Y + y); - } else { - freePos = Vector2I.Zero; - } - - for (int x = -maxDirection.X; x <= maxDirection.X; x++) { // width - if (freePos != Vector2I.Zero) break; - - if (source.Position.X + x >= Level.SizeX || source.Position.X + x < 0) return freePos; // bounds check - - if (Level.Get(source.Position.X + x, source.Position.Y + y).GetType() == typeof(Element)) { - freePos = new Vector2I(source.Position.X + x, source.Position.Y + y); - break; - } - } - } - - return freePos; - } } diff --git a/Scripts/Elements/Water.cs b/Scripts/Elements/Water.cs new file mode 100644 index 0000000..9484f12 --- /dev/null +++ b/Scripts/Elements/Water.cs @@ -0,0 +1,35 @@ +using Godot; + +namespace FOU.Scripts.Elements; + +public class Water : Solid { + public Water(int x, int y, ref Level level) : base(x, y, ref level) { + Color = Colors.Blue; + Color = AddColorVariance(Color); + } + + 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() { + int randomDirection = 1; + if (GD.Randi() % 2 != 0) + randomDirection *= -1; + + if (Level.IsEmpty(Position + Vector2I.Down)) { + Level.Swap(this, Position + Vector2I.Down); + return; + } else if (Level.IsEmpty(Position + Vector2I.Right * randomDirection)) { + Level.Swap(this, Position + Vector2I.Right * randomDirection); + return; + } else if (Level.IsEmpty(Position + Vector2I.Right * randomDirection * -1)) { + Level.Swap(this, Position + Vector2I.Right*randomDirection); + return; + } + } +} diff --git a/Scripts/Level.cs b/Scripts/Level.cs index 068d4ef..0474d17 100644 --- a/Scripts/Level.cs +++ b/Scripts/Level.cs @@ -46,7 +46,7 @@ public class Level { private void MakeItRain(float rainAmount) { if (GD.Randf() < rainAmount) { - WritePixel((int)(GD.Randi() % SizeX), 0, 1); + WritePixel((int)(GD.Randi() % SizeX), 0, 1); } } @@ -69,20 +69,25 @@ public class Level { public Image DrawLevel() { for (int x = 0; x < SizeX; x++) { for (int y = 0; y < SizeY; y++) { - // if (_elements[x,y] == null) continue; - mImage.SetPixel(x,y, _elements[x,y].Color); } } return mImage; } - public void Swap(Element what, Vector2I swapTo) { - Element old = Get(swapTo); - Set(old, what.Position); - Set(what, swapTo); + public void Swap(Element what, Element swapTo) { + Element swap = new Element(what); + + what.Position = swapTo.Position; + _elements[swapTo.Position.X, swapTo.Position.Y] = what; + + swapTo.Position = swap.Position; + _elements[swap.Position.X, swap.Position.Y] = swapTo; } + public void Swap(Element what, Vector2I pos) { + Swap(what, Get(pos)); + } public Element Get(Vector2I where) { if (where.X < 0 || where.X >= SizeX) return null; @@ -98,10 +103,10 @@ public class Level { return _elements[x,y]; } - private void Set(Element what, Vector2I where) { - if (what == null) return; + public bool IsEmpty(Vector2I pos) { + if (pos.X < 0 || pos.X >= SizeX) return false; + if (pos.Y < 0 || pos.Y >= SizeY) return false; - what.Position = where; - _elements[where.X, where.Y] = what; + return Get(pos).GetType() == typeof(Element); } } diff --git a/Scripts/Main.cs b/Scripts/Main.cs index 8132101..a14edc8 100644 --- a/Scripts/Main.cs +++ b/Scripts/Main.cs @@ -31,6 +31,7 @@ public partial class Main : Node2D { float mappedX = mouse.X / GetViewportRect().Size.X * mLevel.SizeX; float mappedY = mouse.Y / GetViewportRect().Size.Y * mLevel.SizeY; + GD.Print($"click: {mouse}"); mLevel.WritePixel((int)mappedX, (int)mappedY, BrushSize); } }