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("TextureSize", (int)newWorldTexture.GetSize().x);
_tileMaterial.SetShaderParam("CoordinateOffsetU", (int)_tileInstanceManager.WorldTextureCoordinateOffset.x);
_tileMaterial.SetShaderParam("CoordinateOffsetV", (int)_tileInstanceManager.WorldTextureCoordinateOffset.y);
_tileMaterial.SetShaderParam("CoordinateOffsetU", (int)_world.WorldTextureCoordinateOffset.x);
_tileMaterial.SetShaderParam("CoordinateOffsetV", (int)_world.WorldTextureCoordinateOffset.y);
}
public void OnGoldCountChanged(int goldCount)

View File

@ -1,11 +1,16 @@
using System.Linq;
using Godot;
using Godot.Collections;
using Vector2 = Godot.Vector2;
using Vector3 = Godot.Vector3;
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
// scene nodes
@ -14,72 +19,6 @@ public class TileInstanceManager : Spatial
// exports
[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.
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("TileHovered", this, nameof(OnTileHovered));
}
return sceneTileChunk;
}
SceneTileChunk FindSceneTileChunkAtIndex(Vector2 chunkIndex)
private SceneTileChunk FindSceneTileChunkAtIndex(Vector2 chunkIndex)
{
foreach (Spatial child in GetChildren())
{
SceneTileChunk sceneTileChunk = child as SceneTileChunk;
if (sceneTileChunk == null)
{
continue;
}
var sceneTileChunk = child as SceneTileChunk;
if (sceneTileChunk == null) continue;
if (sceneTileChunk.ChunkIndex == chunkIndex)
{
return sceneTileChunk;
}
if (sceneTileChunk.ChunkIndex == chunkIndex) return sceneTileChunk;
}
return null;
}
private void HandleWorldTileChange(Array<Vector2> removedChunkIndices, Array<Vector2> addedChunkIndices)
{
Array<SceneTileChunk> removedChunks = new();
foreach (Vector2 chunkIndex in removedChunkIndices)
foreach (var chunkIndex in removedChunkIndices)
{
SceneTileChunk chunk = FindSceneTileChunkAtIndex(chunkIndex);
if (chunk != null)
{
removedChunks.Add(chunk);
}
var chunk = FindSceneTileChunkAtIndex(chunkIndex);
if (chunk != null) removedChunks.Add(chunk);
}
foreach (Vector2 chunkIndex in addedChunkIndices)
foreach (var chunkIndex in addedChunkIndices)
{
SceneTileChunk sceneTileChunk = null;
if (removedChunks.Count > 0)
@ -158,29 +88,77 @@ public class TileInstanceManager : Spatial
sceneTileChunk.ChunkIndex = chunkIndex;
if (ShowHexTiles)
{
foreach (HexTile3D tile3D in sceneTileChunk.TileNodes)
{
foreach (var tile3D in sceneTileChunk.TileNodes)
tile3D.Transform = new Transform(Basis.Identity.Scaled(Vector3.One * 0.95f),
tile3D.Transform.origin);
}
}
_sceneTileChunks.Add(sceneTileChunk);
}
GD.Print("Removed Chunks " + removedChunkIndices.Count);
GD.Print("Added Chunks " + addedChunkIndices.Count);
GD.Print("Removed chunk count: " + removedChunks.Count);
}
public void OnTileClicked(HexTile3D tile)
{
EmitSignal("TileClicked", tile);
}
public void OnTileHovered(HexTile3D 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 NumChunkRows = 3;
public const int NumChunkColumns = NumChunkRows;
private List<Vector2> _activeChunkIndices = new();
private readonly List<Vector2> _addedChunkIndices = new();
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;
// delegate void OnCoordClicked(Vector2 world_pos);
// other members
private Vector2 _centerPlaneCoord;
private readonly List<Vector2> _removedChunkIndices = new();
private TileInstanceManager _tileInstanceManager;
private readonly Image _heightmapImage = new();
private ImageTexture _heightmapTexture;
private readonly Image _tileTypeMapImage = new();
private ImageTexture _viewTileTypeTexture;
// referenced scenes
private readonly PackedScene _worldChunkScene = GD.Load<PackedScene>("res://scenes/WorldChunk.tscn");
private OpenSimplexNoise _noiseGenerator = new();
private TileInstanceManager _tileInstanceManager;
private ImageTexture _viewTileTypeTexture;
public Vector2 CenterChunkIndex = Vector2.Zero;
public Spatial Chunks;
public Color DebugColor;
public HexGrid HexGrid = new();
private OpenSimplexNoise _noiseGenerator = new();
public int Seed = 0;
public GenerationState State = GenerationState.Done;
public Vector2 WorldTextureCoordinateOffset;
public World()
{
@ -85,7 +87,7 @@ public class World : Spatial
public WorldChunk GetOrCreateWorldChunk(int xIndex, int yIndex, Color debugColor)
{
if (IsTileCached(xIndex, yIndex))
if (IsChunkCached(xIndex, yIndex))
{
var cachedChunk = _cachedWorldChunks[new Vector2(xIndex, yIndex)];
return cachedChunk;
@ -94,7 +96,7 @@ public class World : Spatial
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));
}
@ -279,7 +281,7 @@ public class World : Spatial
_viewTileTypeTexture = new ImageTexture();
_viewTileTypeTexture.CreateFromImage(_tileTypeMapImage);
_tileInstanceManager.WorldTextureCoordinateOffset = chunkIndexSouthWest * worldChunkSize;
WorldTextureCoordinateOffset = chunkIndexSouthWest * worldChunkSize;
EmitSignal("OnWorldViewTileTypeImageChanged", _tileTypeMapImage);
EmitSignal("OnHeightmapImageChanged", _heightmapImage);
@ -330,10 +332,7 @@ public class World : Spatial
if (chunk.TileTypeMapFrameCount > 0) numChunksGeneratingTileType++;
}
if (numChunksGeneratingTileType == 0)
{
State = GenerationState.Objects;
}
if (numChunksGeneratingTileType == 0) State = GenerationState.Objects;
}
else if (State == GenerationState.Objects)
{