From 31dbbbf070d9949376dbf663a2e95d3feeea2df7 Mon Sep 17 00:00:00 2001 From: rogo Date: Tue, 17 Oct 2023 14:29:42 +0200 Subject: [PATCH] finalized dirt added base for liquids --- Scenes/main.tscn | 4 ++-- Scripts/Elements/Dirt.cs | 10 +++++++--- Scripts/Elements/Element.cs | 35 ++++++++++++++++++++++------------- Scripts/Elements/Liquid.cs | 34 ++++++++++++++++++++++++++++++++++ Scripts/Elements/Solid.cs | 33 ++++++++++++++++++++++++++++++++- Scripts/Level.cs | 26 ++++++++++++++++---------- 6 files changed, 113 insertions(+), 29 deletions(-) create mode 100644 Scripts/Elements/Liquid.cs diff --git a/Scenes/main.tscn b/Scenes/main.tscn index c663d8a..3fb7cd9 100644 --- a/Scenes/main.tscn +++ b/Scenes/main.tscn @@ -4,8 +4,8 @@ [node name="Main" type="Node2D"] script = ExtResource("1_k1i8e") -BrushSize = 10 -TextureResolution = 0.33 +BrushSize = 3 +TextureResolution = 0.25 [node name="CanvasLayer" type="CanvasLayer" parent="."] diff --git a/Scripts/Elements/Dirt.cs b/Scripts/Elements/Dirt.cs index b2ee35f..050f45a 100644 --- a/Scripts/Elements/Dirt.cs +++ b/Scripts/Elements/Dirt.cs @@ -11,10 +11,14 @@ public class Dirt : Solid { public override bool Update(int currentFrame) { if (!base.Update(currentFrame)) return false; - if (CheckBelow(X, Y)) { - _level.Swap(this, X, Y+1); + Vector2I freePos = Check(this, Vector2I.Down + Vector2I.Right); + + if (freePos != Vector2I.Zero) { // diagonally right + _level.Swap(this, freePos); + return true; } - return true; + + return true; // not necessarily end, subclasses could do some more things } } diff --git a/Scripts/Elements/Element.cs b/Scripts/Elements/Element.cs index e8c4253..cde75f1 100644 --- a/Scripts/Elements/Element.cs +++ b/Scripts/Elements/Element.cs @@ -5,16 +5,15 @@ namespace FOU.Scripts.Elements; public class Element { public Color Color = Colors.Black; - public int X; - public int Y; + public Vector2I Position; protected Level _level; private int _lastUpdate = -1; public Element(int x, int y, ref Level level) { - X = x; - Y = y; + Position.X = x; + Position.Y = y; _level = level; } @@ -31,15 +30,25 @@ public class Element { } public override string ToString() { - return $"{GetType()} {X}:{Y}"; + return $"{GetType()} {Position}"; } - protected bool CheckBelow(int x, int y) { - if (y+1 >= _level.SizeY) return false; + // 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; + // } - if (_level.Get(x, y+1).GetType() == GetType()) - return false; - - return true; - } -} + /// + /// 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; + }} diff --git a/Scripts/Elements/Liquid.cs b/Scripts/Elements/Liquid.cs new file mode 100644 index 0000000..9ceaef8 --- /dev/null +++ b/Scripts/Elements/Liquid.cs @@ -0,0 +1,34 @@ +using Godot; + +namespace FOU.Scripts.Elements; + +public abstract class Liquid : Element { + protected Liquid(int x, int y, ref Level level) : base(x, y, ref level) { } + + protected override Vector2I Check(Element source, Vector2I maxDirection) { + if (GD.Randi() % 2 != 0) + maxDirection.X *= -1; + + Vector2I freePos = Vector2I.Zero; + for (int y = 0; y <= maxDirection.Y; 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); + } + + 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/Solid.cs b/Scripts/Elements/Solid.cs index ae91f76..9498d11 100644 --- a/Scripts/Elements/Solid.cs +++ b/Scripts/Elements/Solid.cs @@ -1,5 +1,36 @@ -namespace FOU.Scripts.Elements; +using Godot; + +namespace FOU.Scripts.Elements; public abstract class Solid : Element { protected Solid(int x, int y, ref Level level) : base(x, y, ref 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/Level.cs b/Scripts/Level.cs index 75910b8..b14b5e0 100644 --- a/Scripts/Level.cs +++ b/Scripts/Level.cs @@ -1,4 +1,5 @@ -using FOU.Scripts.Elements; +using System; +using FOU.Scripts.Elements; using Godot; namespace FOU.Scripts; @@ -63,13 +64,20 @@ public class Level { return mImage; } - public void Swap(Element what, int toSwapX, int toSwapY) { - Element old = Get(toSwapX, toSwapY); - Set(old, what.X, what.Y); - Set(what, toSwapX, toSwapY); + public void Swap(Element what, Vector2I swapTo) { + Element old = Get(swapTo); + Set(old, what.Position); + Set(what, swapTo); } + public Element Get(Vector2I where) { + if (where.X < 0 || where.X >= SizeX) return null; + if (where.Y < 0 || where.Y >= SizeY) return null; + + return _elements[where.X, where.Y]; + } + public Element Get(int x, int y) { if (x < 0 || x >= SizeX) return null; if (y < 0 || y >= SizeY) return null; @@ -77,12 +85,10 @@ public class Level { return _elements[x,y]; } - private void Set(Element what, int x, int y) { + private void Set(Element what, Vector2I where) { if (what == null) return; - what.X = x; - what.Y = y; - _elements[x,y] = what; + what.Position = where; + _elements[where.X, where.Y] = what; } - }