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;
}
-
}