diff --git a/FOU.csproj b/FOU.csproj index 29d95d9..70ab8a3 100644 --- a/FOU.csproj +++ b/FOU.csproj @@ -1,6 +1,6 @@ - + - net6.0 + net8.0 true diff --git a/Scenes/main.tscn b/Scenes/main.tscn index 16de3fc..187b0df 100644 --- a/Scenes/main.tscn +++ b/Scenes/main.tscn @@ -9,6 +9,7 @@ script = ExtResource("1_k1i8e") DebugVisualization = true BrushSize = 2 +RainAmount = 1.0 [node name="CanvasLayer" type="CanvasLayer" parent="."] diff --git a/Scripts/Chunk.cs b/Scripts/Chunk.cs index 7486d7b..ece2b90 100644 --- a/Scripts/Chunk.cs +++ b/Scripts/Chunk.cs @@ -67,29 +67,23 @@ public class Chunk { else RemoveFromChunk(e); } - public void WritePixel(int x, int y, int size) { - int halfsize = size/2; + public void WritePixel(int x, int y) { + if (x < 0 || x >= sizeX || y < 0 || y >= sizeY) { + GD.PrintErr($"Out of bounds for chunk: {x}:{y}"); + return; + } Type type = typeof(T); + object o = Activator.CreateInstance(type, x, y, this); - for (int i = -halfsize; i <= halfsize; i++) { - for (int j = -halfsize; j <= halfsize; j++) { - int X = Mathf.Clamp(x + i, 0, sizeX-1); - int Y = Mathf.Clamp(y + j, 0, sizeY-1); - object o = Activator.CreateInstance(type, X, Y, this); - - // check if not empty: - if (Elements[X,Y].GetType() != typeof(Element)) { - return; - } - - // if (Elements[X,Y].GetType() != type) { - Elements[X, Y].Chunk.RemoveFromChunk(Elements[X, Y]); - Elements[X, Y] = o as Element; - Elements[X, Y].Active = true; - // } - } + // 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].Active = true; } public int ActiveElementsCount() { diff --git a/Scripts/Level.cs b/Scripts/Level.cs index add31b8..e39de58 100644 --- a/Scripts/Level.cs +++ b/Scripts/Level.cs @@ -11,8 +11,8 @@ public class Level { private Chunk[,] chunks; private Image image; - private int chunksX; - private int chunksY; + private int chunksPerX; + private int chunksPerY; // per chunk: private int chunkResX; @@ -22,34 +22,34 @@ public class Level { public Level(Main main, int sizeX, int sizeY) { Resolution = new Vector2I(sizeX, sizeY); - chunksX = main.ChunksPerAxis; - chunksY = main.ChunksPerAxis; + chunksPerX = main.ChunksPerAxis; + chunksPerY = main.ChunksPerAxis; - chunkResX = sizeX / chunksX; - chunkResY = sizeY / chunksY; + chunkResX = sizeX / chunksPerX; + chunkResY = sizeY / chunksPerY; - GD.Print($"Generating level ({sizeX}:{sizeY}) with {chunksX*chunksY} chunks ({chunkResX} * {chunkResY})"); + GD.Print($"Generating level ({sizeX}:{sizeY}) with {chunksPerX*chunksPerY} chunks ({chunkResX} * {chunkResY})"); image = Image.Create(sizeX, sizeY, false, Image.Format.Rgb8); - chunks = new Chunk[chunksX, chunksY]; + chunks = new Chunk[chunksPerX, chunksPerY]; int index = 0; // create all chunks - for (int x = 0; x < chunksX; x++) { - for (int y = 0; y < chunksY; y++) { + for (int x = 0; x < chunksPerX; x++) { + for (int y = 0; y < chunksPerY; y++) { chunks[x, y] = new Chunk(chunkResX, chunkResY, index++); } } // assign neighbors - for (int x = 0; x < chunksX; x++) { - for (int y = 0; y < chunksY; y++) { + for (int x = 0; x < chunksPerX; x++) { + for (int y = 0; y < chunksPerY; y++) { if (y > 0) chunks[x, y].NeighborN = chunks[x, y-1]; - if (y < chunksY-1) chunks[x, y].NeighborS = chunks[x, y+1]; + if (y < chunksPerY-1) chunks[x, y].NeighborS = chunks[x, y+1]; if (x > 0) chunks[x, y].NeighborE = chunks[x-1, y]; - if (x < chunksX-1) chunks[x, y].NeighborW = chunks[x+1, y]; + if (x < chunksPerX-1) chunks[x, y].NeighborW = chunks[x+1, y]; } } } @@ -67,9 +67,9 @@ public class Level { public void StartBenchmark() { GD.Print("benchmark"); - for (int x = 0; x < chunksX; x++) { - for (int y = 0; y < chunksY; y++) { - chunks[x, y].WritePixel(chunkResX/2, chunkResY/2, 100); + for (int x = 0; x < chunksPerX; x++) { + for (int y = 0; y < chunksPerY; y++) { + WritePixel(x * chunkResX/2, y * chunkResY/2, 100); } } } @@ -85,17 +85,66 @@ public class Level { for (int i = 0; i <= rainDrops; i++) { if (GD.Randf() < rainAmount) - WritePixel((int)(GD.Randi() % (chunkResX * chunksX)), 0, 1); + WritePixel((int)(GD.Randi() % (chunkResX * chunksPerX)), 0, 1); } } public void WritePixel(int x, int y, int size) { - chunks[x/chunkResX, y/chunkResY].WritePixel(x % chunkResX, y % chunkResY, size); + int halfsize = size/2; + + for (int i = -halfsize; i <= halfsize; i++) { + for (int j = 0; j < 1; j++) { + // for (int j = -halfsize; j <= halfsize; j++) { + // calculate in-chunk coordinates + int inChunkX = x % chunkResX; + int inChunkY = y % chunkResY; + int brushX = i; + int brushY = j; + + // calculate chunk to write to + int chunkX = x/chunkResX; + if (inChunkX + i < 0) { + chunkX--; + // 320 -22 + brushX = chunkResX + inChunkX + i; + inChunkX = chunkResX - inChunkX; + } else if (inChunkX + i >= chunkResX) { + chunkX++; + inChunkX = 0; + brushX = i % chunkResX; + } + inChunkX += brushX; + + if (chunkX < 0 || chunkX >= chunksPerX) { + GD.PrintErr($"Trying to write out of bounds: {x}:{y}"); + return; + } + + int chunkY = y/chunkResY; + if (inChunkY + j < 0) { + chunkY--; + brushY = chunkResY - (inChunkY + j); + inChunkY = chunkResY - inChunkY; + } else if (inChunkY + j >= chunkResY) { + chunkY++; + inChunkY = 0; + brushY = j % chunkResY; + } + inChunkY += brushY; + + if (chunkY < 0 || chunkY >= chunksPerY) { + GD.PrintErr($"Trying to write out of bounds: {x}:{y}"); + return; + } + + chunks[chunkX, chunkY].WritePixel(inChunkX, inChunkY); + } + } } public Image DrawLevel() { - for (int cx = 0; cx < chunksX; cx++) { - for (int cy = 0; cy < chunksY; cy++) { + for (int cx = 0; cx < chunksPerX; cx++) { + for (int cy = 0; cy < chunksPerY; cy++) { for (int x = 0; x < chunkResX; x++) { for (int y = 0; y < chunkResY; y++) { diff --git a/Scripts/Main.cs b/Scripts/Main.cs index 37dcdf9..b8ca1c9 100644 --- a/Scripts/Main.cs +++ b/Scripts/Main.cs @@ -26,8 +26,12 @@ public partial class Main : Node2D { Instance = this; } - public override void _Process(double delta) { + public override void _PhysicsProcess(double delta) { + base._PhysicsProcess(delta); Level.Update(); + } + + public override void _Process(double delta) { mLevelDrawer.Texture = ImageTexture.CreateFromImage(Level.DrawLevel()); } diff --git a/benchmark.txt b/benchmark.txt index b247ef3..bc9fca6 100644 --- a/benchmark.txt +++ b/benchmark.txt @@ -1,15 +1,22 @@ -# Benchmark +# Benchmark + +Start from editor not rider! ## Settings + - Texture Resolution: 0.5 - CHunks per Axis: 2 - Rain Amount: 0 ## Measurements: + ### original (no optimization): + - idle: 42 - 44 fps - benchmark: 24 fps minimum -### only active: -- idle: 100 fps -- benchmark: 36 fps minimum +### performance-improvements (71db6513f22094e7dd67bd32c7ab86b326f9ad9e) + +- idle before: 89 +- benchmark: 33 +- idle after: 75 diff --git a/project.godot b/project.godot index 37bb172..f95826d 100644 --- a/project.godot +++ b/project.godot @@ -12,7 +12,7 @@ config_version=5 config/name="FOU" run/main_scene="res://Scenes/main.tscn" -config/features=PackedStringArray("4.3", "C#", "Forward Plus") +config/features=PackedStringArray("4.4", "C#", "Forward Plus") config/icon="res://icon.svg" [dotnet]