Use Vector2 instead of Tuple<int, int> as identifier for chunks in World.cs.

Means we only have ~ +/-9.000.000 valid coordinates, but that should be enough for now.
WorldChunkRefactoring
Martin Felis 2023-10-14 21:54:06 +02:00
parent 30b70d1d7a
commit 0ce8a0ddd6
2 changed files with 38 additions and 27 deletions

View File

@ -2,7 +2,7 @@ using Godot;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using Godot.Collections;
public class World : Spatial public class World : Spatial
{ {
@ -25,6 +25,9 @@ public class World : Spatial
// [Export] public Vector2 Size = new Vector2(1, 1); // [Export] public Vector2 Size = new Vector2(1, 1);
// signals // signals
[Signal]
delegate void OnTilesChanged(Array<Vector2> removedChunkIndices, Array<Vector2> addedChunkIndices);
// delegate void OnCoordClicked(Vector2 world_pos); // delegate void OnCoordClicked(Vector2 world_pos);
// other members // other members
@ -33,16 +36,16 @@ public class World : Spatial
private int[] _previousCenterChunkCoord = { 0, 0 }; private int[] _previousCenterChunkCoord = { 0, 0 };
private Rect2 _centerChunkRect2 = new Rect2(); private Rect2 _centerChunkRect2 = new Rect2();
private Random _debugColorRandom = new Random(); private Random _debugColorRandom = new Random();
private Dictionary<Tuple<int, int>, WorldChunk> _cachedWorldChunks; private Godot.Collections.Dictionary<Vector2, WorldChunk> _cachedWorldChunks;
private List<Tuple<int, int>> _activeChunkIndices = new(); private List<Vector2> _activeChunkIndices = new();
private List<Tuple<int, int>> _addedChunkIndices = new(); private List<Vector2> _addedChunkIndices = new();
private List<Tuple<int, int>> _removedChunkIndices = new(); private List<Vector2> _removedChunkIndices = new();
public World() public World()
{ {
Debug.Assert(ChunkSize % 2 == 0); Debug.Assert(ChunkSize % 2 == 0);
_cachedWorldChunks = new Dictionary<Tuple<int, int>, WorldChunk>(); _cachedWorldChunks = new Godot.Collections.Dictionary<Vector2, WorldChunk>();
} }
// Called when the node enters the scene tree for the first time. // Called when the node enters the scene tree for the first time.
@ -58,7 +61,7 @@ public class World : Spatial
{ {
if (IsTileCached(xIndex, yIndex)) if (IsTileCached(xIndex, yIndex))
{ {
WorldChunk cachedChunk = _cachedWorldChunks[new Tuple<int, int>(xIndex, yIndex)]; WorldChunk cachedChunk = _cachedWorldChunks[new Vector2(xIndex, yIndex)];
return cachedChunk; return cachedChunk;
} }
@ -67,7 +70,7 @@ public class World : Spatial
private bool IsTileCached(int xIndex, int yIndex) private bool IsTileCached(int xIndex, int yIndex)
{ {
return _cachedWorldChunks.ContainsKey(new Tuple<int, int>(xIndex, yIndex)); return _cachedWorldChunks.ContainsKey(new Vector2(xIndex, yIndex));
} }
private WorldChunk CreateWorldChunk(int xIndex, int yIndex, Color debugColor) private WorldChunk CreateWorldChunk(int xIndex, int yIndex, Color debugColor)
@ -91,7 +94,7 @@ public class World : Spatial
result.DebugColor.a = 0.6f; result.DebugColor.a = 0.6f;
Chunks.AddChild(result); Chunks.AddChild(result);
Tuple<int, int> chunkIndex = new Tuple<int, int>(xIndex, yIndex); Vector2 chunkIndex = new Vector2(xIndex, yIndex);
_cachedWorldChunks.Add(chunkIndex, result); _cachedWorldChunks.Add(chunkIndex, result);
return result; return result;
@ -100,7 +103,7 @@ public class World : Spatial
public void UpdateCenterChunkFromPlaneCoord(Vector2 planeCoord) public void UpdateCenterChunkFromPlaneCoord(Vector2 planeCoord)
{ {
// mark all chunks as retired // mark all chunks as retired
Dictionary<Tuple<int, int>, WorldChunk> oldCachedChunks = new(_cachedWorldChunks); Godot.Collections.Dictionary<Vector2, WorldChunk> oldCachedChunks = new(_cachedWorldChunks);
// set new center chunk // set new center chunk
var chunkIndex = GetChunkTupleFromPlaneCoord(planeCoord); var chunkIndex = GetChunkTupleFromPlaneCoord(planeCoord);
@ -109,22 +112,22 @@ public class World : Spatial
_centerChunkRect2 = currentChunk.PlaneRect; _centerChunkRect2 = currentChunk.PlaneRect;
// load or create adjacent chunks // load or create adjacent chunks
_activeChunkIndices = new List<Tuple<int, int>>(); _activeChunkIndices = new List<Vector2>();
_activeChunkIndices.Add(new Tuple<int, int>(chunkIndex.Item1 - 1, chunkIndex.Item2 - 1)); _activeChunkIndices.Add(new Vector2(chunkIndex.Item1 - 1, chunkIndex.Item2 - 1));
_activeChunkIndices.Add(new Tuple<int, int>(chunkIndex.Item1, chunkIndex.Item2 - 1)); _activeChunkIndices.Add(new Vector2(chunkIndex.Item1, chunkIndex.Item2 - 1));
_activeChunkIndices.Add(new Tuple<int, int>(chunkIndex.Item1 + 1, chunkIndex.Item2 - 1)); _activeChunkIndices.Add(new Vector2(chunkIndex.Item1 + 1, chunkIndex.Item2 - 1));
_activeChunkIndices.Add(new Tuple<int, int>(chunkIndex.Item1 - 1, chunkIndex.Item2)); _activeChunkIndices.Add(new Vector2(chunkIndex.Item1 - 1, chunkIndex.Item2));
_activeChunkIndices.Add(new Tuple<int, int>(chunkIndex.Item1, chunkIndex.Item2)); _activeChunkIndices.Add(new Vector2(chunkIndex.Item1, chunkIndex.Item2));
_activeChunkIndices.Add(new Tuple<int, int>(chunkIndex.Item1 + 1, chunkIndex.Item2)); _activeChunkIndices.Add(new Vector2(chunkIndex.Item1 + 1, chunkIndex.Item2));
_activeChunkIndices.Add(new Tuple<int, int>(chunkIndex.Item1 - 1, chunkIndex.Item2 + 1)); _activeChunkIndices.Add(new Vector2(chunkIndex.Item1 - 1, chunkIndex.Item2 + 1));
_activeChunkIndices.Add(new Tuple<int, int>(chunkIndex.Item1, chunkIndex.Item2 + 1)); _activeChunkIndices.Add(new Vector2(chunkIndex.Item1, chunkIndex.Item2 + 1));
_activeChunkIndices.Add(new Tuple<int, int>(chunkIndex.Item1 + 1, chunkIndex.Item2 + 1)); _activeChunkIndices.Add(new Vector2(chunkIndex.Item1 + 1, chunkIndex.Item2 + 1));
foreach(Tuple<int, int> activeChunkIndex in _activeChunkIndices) foreach(Vector2 activeChunkIndex in _activeChunkIndices)
{ {
GetOrCreateWorldChunk(activeChunkIndex.Item1, activeChunkIndex.Item2, new Color(GD.Randf(), GD.Randf(), GD.Randf())); GetOrCreateWorldChunk((int) activeChunkIndex.x, (int) activeChunkIndex.y, new Color(GD.Randf(), GD.Randf(), GD.Randf()));
} }
// unload retired chunks // unload retired chunks
@ -147,18 +150,17 @@ public class World : Spatial
} }
} }
GD.Print("Removed Chunks " + _removedChunkIndices.Count); EmitSignal("OnTilesChanged", _removedChunkIndices.ToArray(), _addedChunkIndices.ToArray());
GD.Print("Added Chunks " + _addedChunkIndices.Count);
} }
private void RemoveChunk(Tuple<int, int> cachedChunkKey) private void RemoveChunk(Vector2 cachedChunkKey)
{ {
_cachedWorldChunks.Remove(cachedChunkKey); _cachedWorldChunks.Remove(cachedChunkKey);
_removedChunkIndices.Add(cachedChunkKey); _removedChunkIndices.Add(cachedChunkKey);
foreach (WorldChunk chunk in Chunks.GetChildren()) foreach (WorldChunk chunk in Chunks.GetChildren())
{ {
if (chunk.ChunkAddress == new Vector2(cachedChunkKey.Item1, cachedChunkKey.Item2)) if (chunk.ChunkAddress == new Vector2(cachedChunkKey.x, cachedChunkKey.y))
{ {
chunk.QueueFree(); chunk.QueueFree();
} }

View File

@ -1,5 +1,5 @@
using Godot; using Godot;
using System; using Godot.Collections;
public class WorldView : Spatial public class WorldView : Spatial
{ {
@ -23,9 +23,18 @@ public class WorldView : Spatial
public override void _Ready() public override void _Ready()
{ {
_world = GetNode<World>(World); _world = GetNode<World>(World);
_world.Connect("OnTilesChanged", this, nameof(HandleWorldTileChange));
} }
public override void _Process(float delta) public override void _Process(float delta)
{ {
} }
private void HandleWorldTileChange(Array<Vector2> removedChunkIndices, Array<Vector2> addedChunkIndices)
{
GD.Print("Removed Chunks " + removedChunkIndices.Count);
GD.Print("Added Chunks " + addedChunkIndices.Count);
}
} }