Further cleanup.

WorldChunkRefactoring
Martin Felis 2023-11-01 17:59:43 +01:00
parent 6ca776014b
commit 0663263bb7
3 changed files with 98 additions and 121 deletions

View File

@ -352,8 +352,8 @@ public class Game : Spatial
_tileMaterial.SetShaderParam("MapAlbedoTexture", newWorldTexture); _tileMaterial.SetShaderParam("MapAlbedoTexture", newWorldTexture);
_tileMaterial.SetShaderParam("TextureSize", (int)newWorldTexture.GetSize().x); _tileMaterial.SetShaderParam("TextureSize", (int)newWorldTexture.GetSize().x);
_tileMaterial.SetShaderParam("CoordinateOffsetU", (int)_tileInstanceManager.WorldTextureCoordinateOffset.x); _tileMaterial.SetShaderParam("CoordinateOffsetU", (int)_world.WorldTextureCoordinateOffset.x);
_tileMaterial.SetShaderParam("CoordinateOffsetV", (int)_tileInstanceManager.WorldTextureCoordinateOffset.y); _tileMaterial.SetShaderParam("CoordinateOffsetV", (int)_world.WorldTextureCoordinateOffset.y);
} }
public void OnGoldCountChanged(int goldCount) public void OnGoldCountChanged(int goldCount)

View File

@ -1,11 +1,16 @@
using System.Linq; using System.Linq;
using Godot; using Godot;
using Godot.Collections; using Godot.Collections;
using Vector2 = Godot.Vector2;
using Vector3 = Godot.Vector3;
public class TileInstanceManager : Spatial public class TileInstanceManager : Spatial
{ {
// other members
[Export] public bool ShowHexTiles;
[Export] public Vector2 ViewCenterPlaneCoord;
private World _world;
private readonly Array<SceneTileChunk> _sceneTileChunks = new();
private ImageTexture _viewTileTypeTexture;
// ui elements // ui elements
// scene nodes // scene nodes
@ -14,72 +19,6 @@ public class TileInstanceManager : Spatial
// exports // exports
[Export] public NodePath World; [Export] public NodePath World;
[Export] public Vector2 ViewCenterPlaneCoord;
[Export] public bool ShowHexTiles = false;
// signals
[Signal]
delegate void TileClicked(HexTile3D tile3d);
[Signal]
delegate void TileHovered(HexTile3D tile3d);
// other members
public Vector2 WorldTextureCoordinateOffset = Vector2.Zero;
private World _world;
private ImageTexture _viewTileTypeTexture;
private Image _viewTileTypeImage = new();
private class SceneTileChunk : Spatial
{
private Vector2 _chunkIndex = Vector2.Inf;
public Vector2 ChunkIndex
{
get
{
return _chunkIndex;
}
set
{
Transform chunkTransform = Transform.Identity;
Vector2 chunkOriginPlaneCoord = HexGrid.GetHexCenterFromOffset(value * global::World.ChunkSize);
chunkTransform.origin = new Vector3(chunkOriginPlaneCoord.x, 0, chunkOriginPlaneCoord.y);
Transform = chunkTransform;
_chunkIndex = value;
}
}
public Array<HexTile3D> TileNodes = new();
private PackedScene _hexTile3DScene = GD.Load<PackedScene>("res://scenes/HexTile3D.tscn");
private HexGrid HexGrid = new();
public SceneTileChunk(Vector2 chunkIndex)
{
int chunkSize = global::World.ChunkSize;
foreach (int i in Enumerable.Range(0, chunkSize))
{
foreach (int j in Enumerable.Range(0, chunkSize))
{
HexTile3D tile3D = (HexTile3D)_hexTile3DScene.Instance();
Transform tileTransform = Transform.Identity;
Vector2 centerPlaneCoord = HexGrid.GetHexCenterFromOffset(new Vector2(i, j));
tileTransform.origin = new Vector3(centerPlaneCoord.x, 0, centerPlaneCoord.y);
tile3D.Transform = tileTransform;
TileNodes.Add(tile3D);
AddChild(tile3D);
}
}
ChunkIndex = chunkIndex;
}
}
private Array<SceneTileChunk> _sceneTileChunks = new Array<SceneTileChunk>();
// Called when the node enters the scene tree for the first time. // Called when the node enters the scene tree for the first time.
public override void _Ready() public override void _Ready()
@ -94,52 +33,43 @@ public class TileInstanceManager : Spatial
{ {
} }
SceneTileChunk CreateSceneTileChunk(Vector2 chunkIndex) private SceneTileChunk CreateSceneTileChunk(Vector2 chunkIndex)
{ {
SceneTileChunk sceneTileChunk = new SceneTileChunk(chunkIndex); var sceneTileChunk = new SceneTileChunk(chunkIndex);
foreach (HexTile3D hexTile3D in sceneTileChunk.TileNodes) foreach (var hexTile3D in sceneTileChunk.TileNodes)
{ {
hexTile3D.Connect("TileClicked", this, nameof(OnTileClicked)); hexTile3D.Connect("TileClicked", this, nameof(OnTileClicked));
hexTile3D.Connect("TileHovered", this, nameof(OnTileHovered)); hexTile3D.Connect("TileHovered", this, nameof(OnTileHovered));
} }
return sceneTileChunk; return sceneTileChunk;
} }
SceneTileChunk FindSceneTileChunkAtIndex(Vector2 chunkIndex) private SceneTileChunk FindSceneTileChunkAtIndex(Vector2 chunkIndex)
{ {
foreach (Spatial child in GetChildren()) foreach (Spatial child in GetChildren())
{ {
SceneTileChunk sceneTileChunk = child as SceneTileChunk; var sceneTileChunk = child as SceneTileChunk;
if (sceneTileChunk == null) if (sceneTileChunk == null) continue;
{
continue;
}
if (sceneTileChunk.ChunkIndex == chunkIndex) if (sceneTileChunk.ChunkIndex == chunkIndex) return sceneTileChunk;
{
return sceneTileChunk;
}
} }
return null; return null;
} }
private void HandleWorldTileChange(Array<Vector2> removedChunkIndices, Array<Vector2> addedChunkIndices) private void HandleWorldTileChange(Array<Vector2> removedChunkIndices, Array<Vector2> addedChunkIndices)
{ {
Array<SceneTileChunk> removedChunks = new(); Array<SceneTileChunk> removedChunks = new();
foreach (Vector2 chunkIndex in removedChunkIndices) foreach (var chunkIndex in removedChunkIndices)
{ {
SceneTileChunk chunk = FindSceneTileChunkAtIndex(chunkIndex); var chunk = FindSceneTileChunkAtIndex(chunkIndex);
if (chunk != null) if (chunk != null) removedChunks.Add(chunk);
{
removedChunks.Add(chunk);
}
} }
foreach (Vector2 chunkIndex in addedChunkIndices) foreach (var chunkIndex in addedChunkIndices)
{ {
SceneTileChunk sceneTileChunk = null; SceneTileChunk sceneTileChunk = null;
if (removedChunks.Count > 0) if (removedChunks.Count > 0)
@ -158,29 +88,77 @@ public class TileInstanceManager : Spatial
sceneTileChunk.ChunkIndex = chunkIndex; sceneTileChunk.ChunkIndex = chunkIndex;
if (ShowHexTiles) if (ShowHexTiles)
{ foreach (var tile3D in sceneTileChunk.TileNodes)
foreach (HexTile3D tile3D in sceneTileChunk.TileNodes)
{
tile3D.Transform = new Transform(Basis.Identity.Scaled(Vector3.One * 0.95f), tile3D.Transform = new Transform(Basis.Identity.Scaled(Vector3.One * 0.95f),
tile3D.Transform.origin); tile3D.Transform.origin);
}
}
_sceneTileChunks.Add(sceneTileChunk); _sceneTileChunks.Add(sceneTileChunk);
} }
GD.Print("Removed Chunks " + removedChunkIndices.Count); GD.Print("Removed Chunks " + removedChunkIndices.Count);
GD.Print("Added Chunks " + addedChunkIndices.Count); GD.Print("Added Chunks " + addedChunkIndices.Count);
GD.Print("Removed chunk count: " + removedChunks.Count); GD.Print("Removed chunk count: " + removedChunks.Count);
} }
public void OnTileClicked(HexTile3D tile) public void OnTileClicked(HexTile3D tile)
{ {
EmitSignal("TileClicked", tile); EmitSignal("TileClicked", tile);
} }
public void OnTileHovered(HexTile3D tile) public void OnTileHovered(HexTile3D tile)
{ {
EmitSignal("TileHovered", tile); EmitSignal("TileHovered", tile);
} }
// signals
[Signal]
private delegate void TileClicked(HexTile3D tile3d);
[Signal]
private delegate void TileHovered(HexTile3D tile3d);
private class SceneTileChunk : Spatial
{
private Vector2 _chunkIndex = Vector2.Inf;
private readonly PackedScene _hexTile3DScene = GD.Load<PackedScene>("res://scenes/HexTile3D.tscn");
private readonly HexGrid HexGrid = new();
public readonly Array<HexTile3D> TileNodes = new();
public SceneTileChunk(Vector2 chunkIndex)
{
var chunkSize = global::World.ChunkSize;
foreach (var i in Enumerable.Range(0, chunkSize))
foreach (var j in Enumerable.Range(0, chunkSize))
{
var tile3D = (HexTile3D)_hexTile3DScene.Instance();
var tileTransform = Transform.Identity;
var centerPlaneCoord = HexGrid.GetHexCenterFromOffset(new Vector2(i, j));
tileTransform.origin = new Vector3(centerPlaneCoord.x, 0, centerPlaneCoord.y);
tile3D.Transform = tileTransform;
TileNodes.Add(tile3D);
AddChild(tile3D);
}
ChunkIndex = chunkIndex;
}
public Vector2 ChunkIndex
{
get => _chunkIndex;
set
{
var chunkTransform = Transform.Identity;
var chunkOriginPlaneCoord = HexGrid.GetHexCenterFromOffset(value * global::World.ChunkSize);
chunkTransform.origin = new Vector3(chunkOriginPlaneCoord.x, 0, chunkOriginPlaneCoord.y);
Transform = chunkTransform;
_chunkIndex = value;
}
}
}
} }

View File

@ -20,36 +20,38 @@ public class World : Spatial
public const int ChunkSize = 16; public const int ChunkSize = 16;
public const int NumChunkRows = 3; public const int NumChunkRows = 3;
public const int NumChunkColumns = NumChunkRows; public const int NumChunkColumns = NumChunkRows;
private List<Vector2> _activeChunkIndices = new();
private readonly List<Vector2> _addedChunkIndices = new(); private readonly List<Vector2> _addedChunkIndices = new();
private readonly Godot.Collections.Dictionary<Vector2, WorldChunk> _cachedWorldChunks; private readonly Godot.Collections.Dictionary<Vector2, WorldChunk> _cachedWorldChunks;
private readonly Image _heightmapImage = new();
private readonly List<Vector2> _removedChunkIndices = new();
private readonly Image _tileTypeMapImage = new();
// referenced scenes
private readonly PackedScene _worldChunkScene = GD.Load<PackedScene>("res://scenes/WorldChunk.tscn");
private List<Vector2> _activeChunkIndices = new();
private Rect2 _centerChunkRect; private Rect2 _centerChunkRect;
// delegate void OnCoordClicked(Vector2 world_pos); // delegate void OnCoordClicked(Vector2 world_pos);
// other members // other members
private Vector2 _centerPlaneCoord; private Vector2 _centerPlaneCoord;
private readonly List<Vector2> _removedChunkIndices = new();
private TileInstanceManager _tileInstanceManager;
private readonly Image _heightmapImage = new();
private ImageTexture _heightmapTexture; private ImageTexture _heightmapTexture;
private readonly Image _tileTypeMapImage = new();
private ImageTexture _viewTileTypeTexture;
// referenced scenes private OpenSimplexNoise _noiseGenerator = new();
private readonly PackedScene _worldChunkScene = GD.Load<PackedScene>("res://scenes/WorldChunk.tscn"); private TileInstanceManager _tileInstanceManager;
private ImageTexture _viewTileTypeTexture;
public Vector2 CenterChunkIndex = Vector2.Zero; public Vector2 CenterChunkIndex = Vector2.Zero;
public Spatial Chunks; public Spatial Chunks;
public Color DebugColor; public Color DebugColor;
public HexGrid HexGrid = new(); public HexGrid HexGrid = new();
private OpenSimplexNoise _noiseGenerator = new();
public int Seed = 0; public int Seed = 0;
public GenerationState State = GenerationState.Done; public GenerationState State = GenerationState.Done;
public Vector2 WorldTextureCoordinateOffset;
public World() public World()
{ {
@ -85,7 +87,7 @@ public class World : Spatial
public WorldChunk GetOrCreateWorldChunk(int xIndex, int yIndex, Color debugColor) public WorldChunk GetOrCreateWorldChunk(int xIndex, int yIndex, Color debugColor)
{ {
if (IsTileCached(xIndex, yIndex)) if (IsChunkCached(xIndex, yIndex))
{ {
var cachedChunk = _cachedWorldChunks[new Vector2(xIndex, yIndex)]; var cachedChunk = _cachedWorldChunks[new Vector2(xIndex, yIndex)];
return cachedChunk; return cachedChunk;
@ -94,7 +96,7 @@ public class World : Spatial
return CreateWorldChunk(xIndex, yIndex, debugColor); return CreateWorldChunk(xIndex, yIndex, debugColor);
} }
private bool IsTileCached(int xIndex, int yIndex) private bool IsChunkCached(int xIndex, int yIndex)
{ {
return _cachedWorldChunks.ContainsKey(new Vector2(xIndex, yIndex)); return _cachedWorldChunks.ContainsKey(new Vector2(xIndex, yIndex));
} }
@ -279,7 +281,7 @@ public class World : Spatial
_viewTileTypeTexture = new ImageTexture(); _viewTileTypeTexture = new ImageTexture();
_viewTileTypeTexture.CreateFromImage(_tileTypeMapImage); _viewTileTypeTexture.CreateFromImage(_tileTypeMapImage);
_tileInstanceManager.WorldTextureCoordinateOffset = chunkIndexSouthWest * worldChunkSize; WorldTextureCoordinateOffset = chunkIndexSouthWest * worldChunkSize;
EmitSignal("OnWorldViewTileTypeImageChanged", _tileTypeMapImage); EmitSignal("OnWorldViewTileTypeImageChanged", _tileTypeMapImage);
EmitSignal("OnHeightmapImageChanged", _heightmapImage); EmitSignal("OnHeightmapImageChanged", _heightmapImage);
@ -330,10 +332,7 @@ public class World : Spatial
if (chunk.TileTypeMapFrameCount > 0) numChunksGeneratingTileType++; if (chunk.TileTypeMapFrameCount > 0) numChunksGeneratingTileType++;
} }
if (numChunksGeneratingTileType == 0) if (numChunksGeneratingTileType == 0) State = GenerationState.Objects;
{
State = GenerationState.Objects;
}
} }
else if (State == GenerationState.Objects) else if (State == GenerationState.Objects)
{ {