using Godot; using System; using System.Collections.Generic; using System.Diagnostics; public class World : Spatial { // referenced scenes private PackedScene _worldChunkScene = GD.Load("res://scenes/WorldChunk.tscn"); // constants public const int ChunkSize = 4; public HexGrid HexGrid = new HexGrid(); public Spatial Chunks; public Color DebugColor; // ui elements // scene nodes // resources // exports // [Export] public Vector2 Size = new Vector2(1, 1); // signals // delegate void OnCoordClicked(Vector2 world_pos); // other members private Vector2 _centerPlaneCoord; private int[] _centerChunkCoord = { 0, 0 }; private int[] _previousCenterChunkCoord = { 0, 0 }; private Rect2 _centerChunkRect2 = new Rect2(); private Random _debugColorRandom = new Random(); private Dictionary, WorldChunk> _worldChunks; public World() { Debug.Assert(ChunkSize % 2 == 0); _worldChunks = new Dictionary, WorldChunk>(); } // Called when the node enters the scene tree for the first time. public override void _Ready() { Chunks = (Spatial)FindNode("Chunks"); Debug.Assert(Chunks != null); SetCenterPlaneCoord(Vector2.Zero); } public WorldChunk GetOrCreateWorldChunk(int xIndex, int yIndex, Color debugColor) { if (_worldChunks.ContainsKey(new Tuple(xIndex, yIndex))) { WorldChunk cachedChunk = _worldChunks[new Tuple(xIndex, yIndex)]; return cachedChunk; } return CreateWorldChunk(xIndex, yIndex, debugColor); } private WorldChunk CreateWorldChunk(int xIndex, int yIndex, Color debugColor) { WorldChunk result = (WorldChunk)_worldChunkScene.Instance(); Vector2 offsetCoordSouthWest = new Vector2(xIndex, yIndex) * ChunkSize; Vector2 offsetCoordNorthEast = offsetCoordSouthWest + new Vector2(1, 1) * (ChunkSize - 1); Vector2 planeCoordSouthWest = HexGrid.GetHexCenterFromOffset(offsetCoordSouthWest) + new Vector2(-HexGrid.HexSize.x, HexGrid.HexSize.y) * 0.5f; Vector2 planeCoordNorthEast = HexGrid.GetHexCenterFromOffset(offsetCoordNorthEast) + new Vector2(HexGrid.HexSize.x, -HexGrid.HexSize.y) * 0.5f; result.PlaneRect = new Rect2( new Vector2(planeCoordSouthWest.x, planeCoordNorthEast.y), new Vector2(planeCoordNorthEast.x - planeCoordSouthWest.x, planeCoordSouthWest.y - planeCoordNorthEast.y)); result.DebugColor = debugColor; result.DebugColor.a = 0.6f; Chunks.AddChild(result); Tuple chunkIndex = new Tuple(xIndex, yIndex); _worldChunks.Add(chunkIndex, result); return result; } public void UpdateCenterChunkFromPlaneCoord(Vector2 planeCoord) { HexCell centerOffsetCoord = HexGrid.GetHexAt(planeCoord); Vector2 chunkIndexFloatUnrounded = (centerOffsetCoord.OffsetCoords / (float)ChunkSize); Vector2 chunkIndexFloat = (centerOffsetCoord.OffsetCoords / (float)ChunkSize).Floor(); Tuple chunkIndex = new Tuple((int)chunkIndexFloat.x, (int)chunkIndexFloat.y); WorldChunk currentChunk = GetOrCreateWorldChunk(chunkIndex.Item1, chunkIndex.Item2, new Color(GD.Randf(), GD.Randf(), GD.Randf())); _centerChunkRect2 = currentChunk.PlaneRect; } public void SetCenterPlaneCoord(Vector2 centerPlaneCoord) { if (!_centerChunkRect2.HasPoint(centerPlaneCoord)) { UpdateCenterChunkFromPlaneCoord(centerPlaneCoord); } } // // Called every frame. 'delta' is the elapsed time since the previous frame. // public override void _Process(float delta) // { // // } }