GodotComponentTest/scenes/World.cs

115 lines
3.8 KiB
C#

using Godot;
using System;
using System.Collections.Generic;
using System.Diagnostics;
public class World : Spatial
{
// referenced scenes
private PackedScene _worldChunkScene = GD.Load<PackedScene>("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<Tuple<int, int>, WorldChunk> _worldChunks;
public World()
{
Debug.Assert(ChunkSize % 2 == 0);
_worldChunks = new Dictionary<Tuple<int, int>, 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<int, int>(xIndex, yIndex)))
{
WorldChunk cachedChunk = _worldChunks[new Tuple<int, int>(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<int, int> chunkIndex = new Tuple<int, int>(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<int, int> chunkIndex = new Tuple<int, int>((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)
// {
//
// }
}