Compare commits
17 Commits
abf948a310
...
activate-n
| Author | SHA1 | Date | |
|---|---|---|---|
| 4220e94e38 | |||
| b0b5e95eda | |||
| 7458d5749c | |||
| 9a36418d23 | |||
| f932ae1bcd | |||
| c41cdd57c4 | |||
| e653f23a42 | |||
| 6acccefa0a | |||
| 28ada065a6 | |||
| ea34b8ecc0 | |||
| 4462573267 | |||
| 0b97027e00 | |||
| d9bde10c3c | |||
| 2e4fc22263 | |||
| 202e71d97e | |||
| a119e92bf6 | |||
| da3afd22fc |
@@ -1,4 +1,3 @@
|
|||||||
using System.Reflection;
|
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
public partial class SettingsController : VBoxContainer
|
public partial class SettingsController : VBoxContainer
|
||||||
@@ -18,7 +17,7 @@ public partial class SettingsController : VBoxContainer
|
|||||||
slSize.Value = main.BrushSize;
|
slSize.Value = main.BrushSize;
|
||||||
|
|
||||||
slRain.ValueChanged += OnRainValueChanged;
|
slRain.ValueChanged += OnRainValueChanged;
|
||||||
slRain.Value = main.RainAmount;
|
slRain.Value = main.rainAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSizeValueChanged(double value) {
|
private void OnSizeValueChanged(double value) {
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
[node name="Main" type="Node2D"]
|
[node name="Main" type="Node2D"]
|
||||||
script = ExtResource("1_k1i8e")
|
script = ExtResource("1_k1i8e")
|
||||||
BrushSize = 2
|
DebugMode = true
|
||||||
RainAmount = 1.0
|
BrushSize = 4
|
||||||
|
|
||||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||||
|
|
||||||
@@ -84,6 +84,6 @@ custom_minimum_size = Vector2(150, 0)
|
|||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 8
|
size_flags_horizontal = 8
|
||||||
size_flags_vertical = 1
|
size_flags_vertical = 1
|
||||||
max_value = 5.0
|
max_value = 10.0
|
||||||
step = 0.01
|
step = 0.01
|
||||||
value = 1.0
|
value = 1.0
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ public class Chunk {
|
|||||||
public Chunk NeighborS = null;
|
public Chunk NeighborS = null;
|
||||||
public Chunk NeighborW = null;
|
public Chunk NeighborW = null;
|
||||||
|
|
||||||
private readonly Image image;
|
|
||||||
private readonly int sizeX;
|
private readonly int sizeX;
|
||||||
private readonly int sizeY;
|
private readonly int sizeY;
|
||||||
private readonly HashSet<Element> activeElements;
|
private readonly HashSet<Element> activeElements;
|
||||||
@@ -33,9 +32,6 @@ public class Chunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
activeElements = new HashSet<Element>(sizeX * sizeY);
|
activeElements = new HashSet<Element>(sizeX * sizeY);
|
||||||
|
|
||||||
image = Image.CreateEmpty(sizeX, sizeY, false, Image.Format.Rgb8);
|
|
||||||
image.Fill(Colors.Black);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update() {
|
public void Update() {
|
||||||
@@ -54,14 +50,14 @@ public class Chunk {
|
|||||||
if (toAddElements.Count > 0) {
|
if (toAddElements.Count > 0) {
|
||||||
foreach (Element addElement in toAddElements) {
|
foreach (Element addElement in toAddElements) {
|
||||||
activeElements.Add(addElement);
|
activeElements.Add(addElement);
|
||||||
addElement.SetDebugColor(Colors.Green);
|
addElement.SetDebugColor(addElement.Color * 1.5f);
|
||||||
}
|
}
|
||||||
toAddElements.Clear();
|
toAddElements.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetElementActive(Element e, bool active) {
|
public void SetElementActive(Element e, bool active) {
|
||||||
if (e.GetType() == typeof(Element) && active) return;
|
if (e.GetType() == typeof(Element)) return;
|
||||||
|
|
||||||
if (active) AddToChunk(e);
|
if (active) AddToChunk(e);
|
||||||
else RemoveFromChunk(e);
|
else RemoveFromChunk(e);
|
||||||
@@ -73,15 +69,16 @@ public class Chunk {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if not empty and overwrite not allowed:
|
||||||
|
if (!Elements[x,y].IsEmpty() && !Main.Instance.AllowOverwrite)
|
||||||
|
return;
|
||||||
|
else if (!Elements[x,y].IsEmpty()) {
|
||||||
|
Elements[x, y].Chunk.RemoveFromChunk(Elements[x, y]);
|
||||||
|
}
|
||||||
|
|
||||||
Type type = typeof(T);
|
Type type = typeof(T);
|
||||||
object o = Activator.CreateInstance(type, x, y, this);
|
object o = Activator.CreateInstance(type, x, y, this);
|
||||||
|
|
||||||
// check if not empty:
|
|
||||||
if (Elements[x,y].GetType() != typeof(Element)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Elements[x, y].Chunk.RemoveFromChunk(Elements[x, y]);
|
|
||||||
Elements[x, y] = o as Element;
|
Elements[x, y] = o as Element;
|
||||||
Elements[x, y].Active = true;
|
Elements[x, y].Active = true;
|
||||||
}
|
}
|
||||||
@@ -90,10 +87,6 @@ public class Chunk {
|
|||||||
return activeElements.Count;
|
return activeElements.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Swap(Element what, Vector2I pos) {
|
|
||||||
Swap(what, Get(pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Element Get(Vector2I pos) {
|
public Element Get(Vector2I pos) {
|
||||||
Element e = null;
|
Element e = null;
|
||||||
|
|
||||||
@@ -129,6 +122,10 @@ public class Chunk {
|
|||||||
return Get(pos)?.GetType() == typeof(Element);
|
return Get(pos)?.GetType() == typeof(Element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Swap(Element what, Vector2I pos) {
|
||||||
|
Swap(what, Get(pos));
|
||||||
|
}
|
||||||
|
|
||||||
private void Swap(Element what, Element swapTo) {
|
private void Swap(Element what, Element swapTo) {
|
||||||
if (what == null || swapTo == null) {
|
if (what == null || swapTo == null) {
|
||||||
GD.PrintErr("Trying to swap null");
|
GD.PrintErr("Trying to swap null");
|
||||||
@@ -138,6 +135,9 @@ public class Chunk {
|
|||||||
if (what.Chunk != swapTo.Chunk) {
|
if (what.Chunk != swapTo.Chunk) {
|
||||||
what.Chunk.RemoveFromChunk(what);
|
what.Chunk.RemoveFromChunk(what);
|
||||||
swapTo.Chunk.AddToChunk(what);
|
swapTo.Chunk.AddToChunk(what);
|
||||||
|
|
||||||
|
swapTo.Chunk.RemoveFromChunk(swapTo);
|
||||||
|
what.Chunk.AddToChunk(swapTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Element temp = new Element(what);
|
Element temp = new Element(what);
|
||||||
@@ -152,8 +152,13 @@ public class Chunk {
|
|||||||
|
|
||||||
what.Active = true;
|
what.Active = true;
|
||||||
what.Moved();
|
what.Moved();
|
||||||
|
if (what.IsEmpty())
|
||||||
|
what.ActivateNeighbors();
|
||||||
|
|
||||||
swapTo.Active = true;
|
swapTo.Active = true;
|
||||||
swapTo.Moved();
|
swapTo.Moved();
|
||||||
|
if (swapTo.IsEmpty())
|
||||||
|
swapTo.ActivateNeighbors();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
|
|||||||
@@ -6,45 +6,51 @@ public class Element {
|
|||||||
|
|
||||||
public Chunk Chunk;
|
public Chunk Chunk;
|
||||||
public Vector2I Position;
|
public Vector2I Position;
|
||||||
|
public int Density;
|
||||||
|
|
||||||
protected int Density;
|
|
||||||
protected int DiffuseSpeed = 10;
|
protected int DiffuseSpeed = 10;
|
||||||
protected Color color = Colors.Black;
|
protected Color color = Colors.Black;
|
||||||
protected const int MAX_DIFFUSE_SPEED = 100;
|
protected const int MAX_DIFFUSE_SPEED = 100;
|
||||||
protected const int STEPS_UNTIL_INACTIVE = 500;
|
protected const int STEPS_UNTIL_INACTIVE = 500;
|
||||||
|
|
||||||
protected const float MAX_COLOR_VARIANCE = 0.1f;
|
|
||||||
protected static readonly Vector2I VERTICAL_OPPOSITE = new Vector2I(-1, 1);
|
protected static readonly Vector2I VERTICAL_OPPOSITE = new Vector2I(-1, 1);
|
||||||
protected int lastMove = 0;
|
private const float MAX_COLOR_VARIANCE = 0.1f;
|
||||||
|
|
||||||
private bool active = false;
|
private bool active = false;
|
||||||
private bool wasMovedThisTick = false;
|
private bool markedForUpdate = true;
|
||||||
private int lastUpdate = -1;
|
private int lastUpdate = -1;
|
||||||
|
private int lastMove = 0;
|
||||||
private Color originalColor;
|
private Color originalColor;
|
||||||
|
|
||||||
public Element(Element e) {
|
public Element(Element e) {
|
||||||
Position = e.Position;
|
Position = e.Position;
|
||||||
Chunk = e.Chunk;
|
Chunk = e.Chunk;
|
||||||
lastMove = Engine.GetFramesDrawn();
|
Active = e.active;
|
||||||
|
lastMove = e.lastMove;
|
||||||
|
lastUpdate = e.lastUpdate;
|
||||||
|
Chunk.SetElementActive(this, Active);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element(int x, int y, Chunk chunk) {
|
public Element(int x, int y, Chunk chunk, bool active = true) {
|
||||||
Position.X = x;
|
Position.X = x;
|
||||||
Position.Y = y;
|
Position.Y = y;
|
||||||
Chunk = chunk;
|
Chunk = chunk;
|
||||||
lastMove = Engine.GetFramesDrawn();
|
lastMove = Engine.GetFramesDrawn();
|
||||||
Active = false;
|
Chunk.SetElementActive(this, Active);
|
||||||
wasMovedThisTick = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Active {
|
public bool Active {
|
||||||
get => active;
|
get => active;
|
||||||
set {
|
set {
|
||||||
if (active == value) return;
|
if (active == value) return;
|
||||||
|
|
||||||
active = value;
|
active = value;
|
||||||
Chunk.SetElementActive(this, value);
|
Chunk.SetElementActive(this, value);
|
||||||
|
|
||||||
|
if (active) {
|
||||||
Moved();
|
Moved();
|
||||||
|
} else {
|
||||||
|
ResetColor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +64,13 @@ public class Element {
|
|||||||
public virtual bool Update() {
|
public virtual bool Update() {
|
||||||
if (!Active) return false;
|
if (!Active) return false;
|
||||||
|
|
||||||
if (lastUpdate == Engine.GetFramesDrawn()) return false; // already updated this frame
|
int frame = Engine.GetFramesDrawn();
|
||||||
lastUpdate = Engine.GetFramesDrawn();
|
if (lastMove + STEPS_UNTIL_INACTIVE < frame)
|
||||||
|
Active = false;
|
||||||
|
if (lastUpdate == frame)
|
||||||
|
return false; // already updated this frame
|
||||||
|
|
||||||
|
lastUpdate = frame;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,24 +78,7 @@ public class Element {
|
|||||||
return $"{GetType()} {Position}[{Chunk.Index}] {active}";
|
return $"{GetType()} {Position}[{Chunk.Index}] {active}";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Tick() {
|
protected virtual void Tick() { }
|
||||||
Vector2I randomDirection = RandomDirectionDown();
|
|
||||||
wasMovedThisTick = false;
|
|
||||||
|
|
||||||
if (Chunk.IsEmpty(Position + Vector2I.Down))
|
|
||||||
Chunk.Swap(this, Position + Vector2I.Down);
|
|
||||||
|
|
||||||
else if (Chunk.IsEmpty(Position + randomDirection))
|
|
||||||
Chunk.Swap(this, Position + randomDirection);
|
|
||||||
|
|
||||||
else if (Chunk.IsEmpty(Position + randomDirection * VERTICAL_OPPOSITE))
|
|
||||||
Chunk.Swap(this, Position + randomDirection * VERTICAL_OPPOSITE);
|
|
||||||
|
|
||||||
if (GD.Randi() % MAX_DIFFUSE_SPEED > DiffuseSpeed) return; // ascend slower
|
|
||||||
|
|
||||||
if (Chunk.Get(Position + randomDirection)?.Density < Density)
|
|
||||||
Chunk.Swap(this, Position + Vector2I.Down);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Vector2I RandomDirectionDown() {
|
protected Vector2I RandomDirectionDown() {
|
||||||
int randomDirection = GD.Randi() % 2 != 0 ? 1 : -1;
|
int randomDirection = GD.Randi() % 2 != 0 ? 1 : -1;
|
||||||
@@ -94,6 +87,13 @@ public class Element {
|
|||||||
+ (GD.Randi() % 2 != 0 ? Vector2I.Zero : Vector2I.Right * randomDirection);
|
+ (GD.Randi() % 2 != 0 ? Vector2I.Zero : Vector2I.Right * randomDirection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <returns>-1, 0 or 1</returns>
|
||||||
|
protected Vector2I RandomDirection() {
|
||||||
|
int randomDirection = GD.Randi() % 2 != 0 ? 1 : -1;
|
||||||
|
|
||||||
|
return (GD.Randi() % 2 != 0 ? Vector2I.Zero : Vector2I.Right * randomDirection);
|
||||||
|
}
|
||||||
|
|
||||||
protected Color AddColorVariance(Color baseColor) {
|
protected Color AddColorVariance(Color baseColor) {
|
||||||
Color c = baseColor;
|
Color c = baseColor;
|
||||||
c.R += (GD.Randf() - 1) * MAX_COLOR_VARIANCE;
|
c.R += (GD.Randf() - 1) * MAX_COLOR_VARIANCE;
|
||||||
@@ -106,21 +106,48 @@ public class Element {
|
|||||||
|
|
||||||
public void ResetColor() {
|
public void ResetColor() {
|
||||||
color = originalColor;
|
color = originalColor;
|
||||||
|
MarkForUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDebugColor(Color color) {
|
public void SetDebugColor(Color color) {
|
||||||
if (!Main.Instance.DebugMode) return;
|
if (!Main.Instance.DebugMode) return;
|
||||||
|
|
||||||
this.color = color;
|
this.color = color;
|
||||||
wasMovedThisTick = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Moved() {
|
public void Moved() {
|
||||||
lastMove = Engine.GetFramesDrawn();
|
lastMove = Engine.GetFramesDrawn();
|
||||||
wasMovedThisTick = true;
|
MarkForUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool WasMoved() {
|
public bool IsMarkedForUpdate() {
|
||||||
return wasMovedThisTick;
|
return markedForUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MarkForUpdate(bool mark = true) {
|
||||||
|
markedForUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEmpty() {
|
||||||
|
return GetType() == typeof(Element);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void ActivateNeighbors() {
|
||||||
|
|
||||||
|
Element n = Chunk.Get(Position + Vector2I.Up);
|
||||||
|
if (n != null && !n.IsEmpty())
|
||||||
|
n.Active = true;
|
||||||
|
//
|
||||||
|
// Element e = Chunk.Get(Position + Vector2I.Right);
|
||||||
|
// if (e != null && !e.IsEmpty())
|
||||||
|
// e.Active = true;
|
||||||
|
//
|
||||||
|
// Element s = Chunk.Get(Position + Vector2I.Down);
|
||||||
|
// if (null != s && !s.IsEmpty())
|
||||||
|
// s.Active = true;
|
||||||
|
//
|
||||||
|
// Element w = Chunk.Get(Position + Vector2I.Left);
|
||||||
|
// if (null != w && !w.IsEmpty())
|
||||||
|
// w.Active = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,18 +5,19 @@ namespace FOU.Scripts.Elements;
|
|||||||
public abstract class Liquid : Element {
|
public abstract class Liquid : Element {
|
||||||
public const int MAX_VERTICAL_SPREAD = 3;
|
public const int MAX_VERTICAL_SPREAD = 3;
|
||||||
|
|
||||||
protected Liquid(int x, int y, ref Chunk chunk) : base(x, y, chunk) { }
|
protected Liquid(int x, int y, ref Chunk chunk) : base(x, y, chunk) {
|
||||||
|
MarkForUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
public override bool Update() {
|
public override bool Update() {
|
||||||
if (!base.Update()) return false;
|
if (!base.Update()) return false;
|
||||||
if (lastMove + STEPS_UNTIL_INACTIVE < Engine.GetFramesDrawn()) Active = false;
|
|
||||||
|
|
||||||
Tick();
|
Tick();
|
||||||
|
|
||||||
return true; // not necessarily end, subclasses could do some more things
|
return true; // not necessarily end, subclasses could do some more things
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Tick() {
|
protected virtual void Tick() {
|
||||||
Vector2I randomDirection = RandomDirectionDown();
|
Vector2I randomDirection = RandomDirectionDown();
|
||||||
if (randomDirection.Y != 0)
|
if (randomDirection.Y != 0)
|
||||||
randomDirection *= Vector2I.Left * (int)(GD.Randi() % MAX_VERTICAL_SPREAD);
|
randomDirection *= Vector2I.Left * (int)(GD.Randi() % MAX_VERTICAL_SPREAD);
|
||||||
@@ -25,9 +26,34 @@ public abstract class Liquid : Element {
|
|||||||
Chunk.Swap(this, Position + Vector2I.Down);
|
Chunk.Swap(this, Position + Vector2I.Down);
|
||||||
|
|
||||||
else if (Chunk.IsEmpty(Position + randomDirection))
|
else if (Chunk.IsEmpty(Position + randomDirection))
|
||||||
Chunk.Swap(this, Position + Vector2I.Right * randomDirection);
|
Chunk.Swap(this, Position + randomDirection);
|
||||||
|
else if (Chunk.IsEmpty(Position + randomDirection * VERTICAL_OPPOSITE))
|
||||||
|
Chunk.Swap(this, Position + randomDirection * VERTICAL_OPPOSITE);
|
||||||
|
|
||||||
else if (Chunk.IsEmpty(Position + randomDirection))
|
else if (Chunk.IsEmpty(Position + 1 * randomDirection))
|
||||||
Chunk.Swap(this, Position + Vector2I.Right * randomDirection * VERTICAL_OPPOSITE);
|
Chunk.Swap(this, Position + 1 * randomDirection);
|
||||||
|
else if (Chunk.IsEmpty(Position - 1 * randomDirection * VERTICAL_OPPOSITE))
|
||||||
|
Chunk.Swap(this, Position - 1 * randomDirection * VERTICAL_OPPOSITE);
|
||||||
|
|
||||||
|
else if (Chunk.IsEmpty(Position + 2 * randomDirection))
|
||||||
|
Chunk.Swap(this, Position + 2 * randomDirection);
|
||||||
|
else if (Chunk.IsEmpty(Position - 2 * randomDirection * VERTICAL_OPPOSITE))
|
||||||
|
Chunk.Swap(this, Position - 2 * randomDirection * VERTICAL_OPPOSITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ActivateNeighbors() {
|
||||||
|
|
||||||
|
Element n = Chunk.Get(Position + Vector2I.Up);
|
||||||
|
if (n != null && !n.IsEmpty())
|
||||||
|
n.Active = true;
|
||||||
|
|
||||||
|
// only activate liquids left or right
|
||||||
|
Element e = Chunk.Get(Position + Vector2I.Right);
|
||||||
|
if (e != null && e.GetType() == typeof(Liquid))
|
||||||
|
e.Active = true;
|
||||||
|
|
||||||
|
Element s = Chunk.Get(Position + Vector2I.Down);
|
||||||
|
if (null != s && s.GetType() == typeof(Liquid))
|
||||||
|
s.Active = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,40 @@
|
|||||||
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 Chunk chunk) : base(x, y, chunk) { }
|
protected Solid(int x, int y, ref Chunk chunk) : base(x, y, chunk) {
|
||||||
|
MarkForUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
public override bool Update() {
|
public override bool Update() {
|
||||||
if (!base.Update()) return false;
|
if (!base.Update()) return false;
|
||||||
if (lastMove + STEPS_UNTIL_INACTIVE < Engine.GetFramesDrawn()) Active = false;
|
|
||||||
|
|
||||||
Tick();
|
Tick();
|
||||||
|
|
||||||
return true; // not necessarily end, subclasses could do some more things
|
return true; // not necessarily end, subclasses could do some more things
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void Tick() {
|
||||||
|
Vector2I randomDirection = RandomDirectionDown();
|
||||||
|
|
||||||
|
// fall speed reduction:
|
||||||
|
if (GD.Randi() % MAX_DIFFUSE_SPEED > DiffuseSpeed) return; // descend slower
|
||||||
|
|
||||||
|
if (Chunk.IsEmpty(Position + Vector2I.Down))
|
||||||
|
Chunk.Swap(this, Position + Vector2I.Down);
|
||||||
|
|
||||||
|
else if (Chunk.IsEmpty(Position + Vector2I.Down + randomDirection))
|
||||||
|
Chunk.Swap(this, Position + Vector2I.Down + randomDirection);
|
||||||
|
|
||||||
|
else if (Chunk.IsEmpty(Position + Vector2I.Down + randomDirection * VERTICAL_OPPOSITE))
|
||||||
|
Chunk.Swap(this, Position + Vector2I.Down + randomDirection * VERTICAL_OPPOSITE);
|
||||||
|
|
||||||
|
// density check
|
||||||
|
if (Chunk.Get(Position + Vector2I.Down)?.Density < Density)
|
||||||
|
Chunk.Swap(this, Position + Vector2I.Down);
|
||||||
|
else if (Chunk.Get(Position + Vector2I.Down + randomDirection)?.Density < Density)
|
||||||
|
Chunk.Swap(this, Position + Vector2I.Down + randomDirection);
|
||||||
|
else if (Chunk.Get(Position + Vector2I.Down + randomDirection * VERTICAL_OPPOSITE)?.Density < Density)
|
||||||
|
Chunk.Swap(this, Position + Vector2I.Down + randomDirection * VERTICAL_OPPOSITE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class Level {
|
|||||||
|
|
||||||
GD.Print($"Generating level ({sizeX}:{sizeY}) with {chunksPerX*chunksPerY} chunks ({chunkResX} * {chunkResY})");
|
GD.Print($"Generating level ({sizeX}:{sizeY}) with {chunksPerX*chunksPerY} chunks ({chunkResX} * {chunkResY})");
|
||||||
|
|
||||||
image = Image.Create(sizeX, sizeY, false, Image.Format.Rgb8);
|
image = Image.CreateEmpty(sizeX, sizeY, false, Image.Format.Rgb8);
|
||||||
|
|
||||||
chunks = new Chunk[chunksPerX, chunksPerY];
|
chunks = new Chunk[chunksPerX, chunksPerY];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@@ -84,8 +84,11 @@ public class Level {
|
|||||||
int rainDrops = (int)Math.Round(rainAmount);
|
int rainDrops = (int)Math.Round(rainAmount);
|
||||||
|
|
||||||
for (int i = 0; i <= rainDrops; i++) {
|
for (int i = 0; i <= rainDrops; i++) {
|
||||||
if (GD.Randf() < rainAmount)
|
if (GD.Randf() < rainAmount) {
|
||||||
WritePixel<Water>((int)(GD.Randi() % (chunkResX * chunksPerX)), 0, 1);
|
int d = (int)(GD.Randi() % (chunkResX * chunksPerX));
|
||||||
|
if (GetElement(d, 0).IsEmpty())
|
||||||
|
WritePixel<Water>(d, 0, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,28 +116,26 @@ public class Level {
|
|||||||
iteratorX = chunkResX + startPtX + iteratorX;
|
iteratorX = chunkResX + startPtX + iteratorX;
|
||||||
ptX = startPtX + iteratorX;
|
ptX = startPtX + iteratorX;
|
||||||
|
|
||||||
// right of chunk
|
|
||||||
} else if (startPtX + iteratorX >= chunkResX) {
|
|
||||||
chunkX++;
|
|
||||||
ptX = startPtX + iteratorX - chunkResX;
|
|
||||||
} else {
|
} else {
|
||||||
ptX = startPtX + iteratorX;
|
ptX = startPtX + iteratorX;
|
||||||
}
|
}
|
||||||
|
if (startPtX + iteratorX >= chunkResX) {
|
||||||
|
chunkX++;
|
||||||
|
ptX = startPtX + iteratorX - chunkResX;
|
||||||
|
}
|
||||||
int chunkY = y/chunkResY;
|
int chunkY = y/chunkResY;
|
||||||
|
|
||||||
// above chunk
|
// above chunk
|
||||||
if (startPtY + iteratorY < 0) {
|
if (startPtY + iteratorY < 0) {
|
||||||
chunkY--;
|
chunkY--;
|
||||||
ptY = chunkResY + (startPtY + iteratorY);
|
ptY = chunkResY + (startPtY + iteratorY);
|
||||||
|
|
||||||
// left of chunk
|
|
||||||
} else if (startPtY + iteratorY >= chunkResY) {
|
|
||||||
chunkY++;
|
|
||||||
ptY = iteratorY % chunkResY;
|
|
||||||
} else {
|
} else {
|
||||||
ptY = startPtY + iteratorY;
|
ptY = startPtY + iteratorY;
|
||||||
}
|
}
|
||||||
|
if (startPtY + iteratorY >= chunkResY) {
|
||||||
|
chunkY++;
|
||||||
|
ptY = startPtY + iteratorY - chunkResY;
|
||||||
|
}
|
||||||
|
|
||||||
// ignore everything outside
|
// ignore everything outside
|
||||||
if (chunkX < 0) continue;
|
if (chunkX < 0) continue;
|
||||||
@@ -147,6 +148,13 @@ public class Level {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Element GetElement(int x, int y) {
|
||||||
|
if (x < 0 || x > chunkResX * chunkResX) return null;
|
||||||
|
if (y < 0 || y > chunkResY * chunkResY) return null;
|
||||||
|
|
||||||
|
return chunks[x / chunkResX, y / chunkResY].Elements[x % chunkResX, y % chunkResY];
|
||||||
|
}
|
||||||
|
|
||||||
public Image DrawLevel() {
|
public Image DrawLevel() {
|
||||||
// chunk
|
// chunk
|
||||||
for (int cx = 0; cx < chunksPerX; cx++) {
|
for (int cx = 0; cx < chunksPerX; cx++) {
|
||||||
@@ -157,8 +165,10 @@ public class Level {
|
|||||||
for (int y = 0; y < chunkResY; y++) {
|
for (int y = 0; y < chunkResY; y++) {
|
||||||
// TODO: multithreading here! use Chunk.DrawLevel() and stitch images together
|
// TODO: multithreading here! use Chunk.DrawLevel() and stitch images together
|
||||||
|
|
||||||
if (chunks[cx, cy].Elements[x, y].WasMoved())
|
if (chunks[cx, cy].Elements[x, y].IsMarkedForUpdate()) {
|
||||||
image.SetPixel(cx * chunkResX + x, cy * chunkResY + y, chunks[cx, cy].Elements[x, y].Color);
|
image.SetPixel(cx * chunkResX + x, cy * chunkResY + y, chunks[cx, cy].Elements[x, y].Color);
|
||||||
|
chunks[cx, cy].Elements[x, y].MarkForUpdate(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,18 +4,26 @@ using Godot;
|
|||||||
|
|
||||||
public partial class Main : Node2D {
|
public partial class Main : Node2D {
|
||||||
[Export] public bool DebugMode = false;
|
[Export] public bool DebugMode = false;
|
||||||
|
[Export] public bool AllowOverwrite = true;
|
||||||
|
|
||||||
[Export] public int BrushSize = 5;
|
[Export] public int BrushSize = 5;
|
||||||
[Export] public float TextureResolution = 0.5f;
|
[Export] public float TextureResolution = 0.5f;
|
||||||
[Export] public int ChunksPerAxis = 2;
|
[Export] public int ChunksPerAxis = 2;
|
||||||
[Export] public float RainAmount = 0;
|
[Export] public float rainAmount = 0;
|
||||||
|
|
||||||
public static Main Instance;
|
public static Main Instance;
|
||||||
public Level Level;
|
public Level Level;
|
||||||
|
|
||||||
private TextureRect mLevelDrawer;
|
private TextureRect mLevelDrawer;
|
||||||
private bool enableRain;
|
private bool enableRain;
|
||||||
private float rainAmount;
|
|
||||||
|
public float RainAmount {
|
||||||
|
get => rainAmount;
|
||||||
|
set {
|
||||||
|
rainAmount = value;
|
||||||
|
Level?.SetRainAmount(rainAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void _Ready() {
|
public override void _Ready() {
|
||||||
Level = new Level(this, (int)(GetViewportRect().Size.X * TextureResolution),
|
Level = new Level(this, (int)(GetViewportRect().Size.X * TextureResolution),
|
||||||
@@ -28,10 +36,10 @@ public partial class Main : Node2D {
|
|||||||
|
|
||||||
public override void _PhysicsProcess(double delta) {
|
public override void _PhysicsProcess(double delta) {
|
||||||
base._PhysicsProcess(delta);
|
base._PhysicsProcess(delta);
|
||||||
Level.Update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _Process(double delta) {
|
public override void _Process(double delta) {
|
||||||
|
Level.Update();
|
||||||
mLevelDrawer.Texture?.Dispose();
|
mLevelDrawer.Texture?.Dispose();
|
||||||
mLevelDrawer.Texture = ImageTexture.CreateFromImage(Level.DrawLevel());
|
mLevelDrawer.Texture = ImageTexture.CreateFromImage(Level.DrawLevel());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user