added falling sand - dirt actually

This commit is contained in:
2023-10-16 15:41:33 +02:00
parent 8a6004af24
commit fe40e33d36
6 changed files with 113 additions and 19 deletions

View File

@@ -2,8 +2,9 @@
[ext_resource type="Script" path="res://Scripts/Main.cs" id="1_k1i8e"] [ext_resource type="Script" path="res://Scripts/Main.cs" id="1_k1i8e"]
[node name="Node2D" type="Node2D"] [node name="Main" type="Node2D"]
script = ExtResource("1_k1i8e") script = ExtResource("1_k1i8e")
BrushSize = 10
[node name="CanvasLayer" type="CanvasLayer" parent="."] [node name="CanvasLayer" type="CanvasLayer" parent="."]

View File

@@ -3,7 +3,18 @@
namespace FOU.Scripts.Elements; namespace FOU.Scripts.Elements;
public class Dirt : Solid { public class Dirt : Solid {
public Dirt() {
public Dirt(int x, int y, ref Level level) : base(x, y, ref level) {
Color = Colors.Brown; Color = Colors.Brown;
} }
public override bool Update(int currentFrame) {
if (!base.Update(currentFrame)) return false;
if (CheckBelow(X, Y)) {
_level.Swap(this, X, Y+1);
}
return true;
}
} }

View File

@@ -2,6 +2,44 @@
namespace FOU.Scripts.Elements; namespace FOU.Scripts.Elements;
public abstract class Element { public class Element {
public Color Color = Colors.Black; public Color Color = Colors.Black;
public int X;
public int Y;
protected Level _level;
private int _lastUpdate = -1;
public Element(int x, int y, ref Level level) {
X = x;
Y = y;
_level = level;
}
/// <summary>
/// base update method, checks if anything is to do at all
/// </summary>
/// <param name="currentFrame"></param>
/// <returns>false if there is nothing to do</returns>
public virtual bool Update(int currentFrame) {
if (_lastUpdate == currentFrame) return false; // already updated this frame
_lastUpdate = currentFrame;
return true;
}
public override string ToString() {
return $"{X}:{Y}";
}
protected bool CheckBelow(int x, int y) {
if (y+1 >= _level.SizeY) return false;
if (_level.Get(x, y+1).GetType() == GetType())
return false;
return true;
}
} }

View File

@@ -1,5 +1,5 @@
namespace FOU.Scripts.Elements; namespace FOU.Scripts.Elements;
public abstract class Solid : Element { public abstract class Solid : Element {
protected Solid(int x, int y, ref Level level) : base(x, y, ref level) { }
} }

View File

@@ -4,41 +4,83 @@ using Godot;
namespace FOU.Scripts; namespace FOU.Scripts;
public class Level { public class Level {
private int mSizeX; public int SizeX;
private int mSizeY; public int SizeY;
private Image mImage; private Image mImage;
private int _frame;
private Element[,] mPixels; private Element[,] _elements;
private Level _this;
public Level(int x, int y) { public Level(int x, int y) {
GD.Print($"Generating level ({x}:{y})"); GD.Print($"Generating level ({x}:{y})");
_this = this;
mSizeX = x; SizeX = x;
mSizeY = y; SizeY = y;
mPixels = new Element[x, y]; _elements = new Element[x, y];
mImage = Image.Create(mSizeX, mSizeY, false, Image.Format.Rgb8); for (int i = 0; i < SizeX; i++) {
for (int j = 0; j < SizeY; j++) {
_elements[i,j] = new Element(i, j, ref _this);
}
}
mImage = Image.Create(SizeX, SizeY, false, Image.Format.Rgb8);
mImage.Fill(Colors.Black); mImage.Fill(Colors.Black);
} }
public void Update() {
for (int x = 0; x < SizeX; x++) {
for (int y = 0; y < SizeY; y++) {
if (_elements[x,y] != null)
_elements[x,y].Update(_frame);
}
}
_frame++;
}
public void WritePixel(int x, int y, int size) { public void WritePixel(int x, int y, int size) {
for (int i = -size/2; i < size/2; i++) { for (int i = -size/2; i < size/2; i++) {
for (int j = -size/2; j < size/2; j++) { for (int j = -size/2; j < size/2; j++) {
int X = Mathf.Clamp(x + i, 0, mSizeX); int X = Mathf.Clamp(x + i, 0, SizeX);
int Y = Mathf.Clamp(y + j, 0, mSizeY); int Y = Mathf.Clamp(y + j, 0, SizeY);
mPixels[X,Y] = new Dirt(); _elements[X,Y] = new Dirt(X, Y, ref _this);
} }
} }
} }
public Image DrawLevel() { public Image DrawLevel() {
for (int x = 0; x < mSizeX; x++) { for (int x = 0; x < SizeX; x++) {
for (int y = 0; y < mSizeY; y++) { for (int y = 0; y < SizeY; y++) {
if (mPixels[x,y] == null) continue; // if (_elements[x,y] == null) continue;
mImage.SetPixel(x,y, mPixels[x,y].Color); mImage.SetPixel(x,y, _elements[x,y].Color);
} }
} }
return mImage; 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 Element Get(int x, int y) {
if (x < 0 || x >= SizeX) return null;
if (y < 0 || y >= SizeY) return null;
return _elements[x,y];
}
private void Set(Element what, int x, int y) {
if (what == null) return;
what.X = x;
what.Y = y;
_elements[x,y] = what;
}
} }

View File

@@ -2,7 +2,7 @@ using FOU.Scripts;
using Godot; using Godot;
public partial class Main : Node2D { public partial class Main : Node2D {
[Export] public int BrushSize = 10; [Export] public int BrushSize = 5;
private TextureRect mLevelDrawer; private TextureRect mLevelDrawer;
private Level mLevel; private Level mLevel;
@@ -13,6 +13,8 @@ public partial class Main : Node2D {
} }
public override void _Process(double delta) { public override void _Process(double delta) {
mLevel.Update();
mLevelDrawer.Texture = ImageTexture.CreateFromImage(mLevel.DrawLevel()); mLevelDrawer.Texture = ImageTexture.CreateFromImage(mLevel.DrawLevel());
} }