Advertisement
AriesOnThat

ChunkManager.cs

Sep 4th, 2024
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.74 KB | None | 0 0
  1. using Godot;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading;
  6.  
  7. [Tool]
  8. public partial class ChunkManager : Node
  9. {
  10.     public static ChunkManager Instance { get; private set; }
  11.  
  12.     private Dictionary<Chunk, Vector2I> _chunkToPosition = new();
  13.     private Dictionary<Vector2I, Chunk> _positionToChunk = new();
  14.  
  15.     private List<Chunk> _chunks;
  16.  
  17.     [Export] public PackedScene ChunkScene { get; set; }
  18.  
  19.     private int _width = 16;
  20.  
  21.     private Vector3 _playerPosition;
  22.     private object _playerPositionLock = new();
  23.  
  24.  
  25.  
  26.     public override void _Ready()
  27.     {
  28.         Instance = this;
  29.  
  30.         _chunks = GetParent().GetChildren().Where(child => child is Chunk).Select(child => child as Chunk).ToList();
  31.  
  32.         for (int i = _chunks.Count; i < _width * _width; i++)
  33.         {
  34.             var chunk = ChunkScene.Instantiate<Chunk>();
  35.             GetParent().CallDeferred(Node.MethodName.AddChild, chunk);
  36.             _chunks.Add(chunk);
  37.         }
  38.  
  39.         for (int x = 0; x < _width; x++)
  40.         {
  41.             for (int y = 0; y < _width; y++)
  42.             {
  43.                 var index = (y * _width) + x;
  44.                 var halfWidth = Mathf.FloorToInt(_width / 2f);
  45.                 Vector2I position = new Vector2I(x - halfWidth, y - halfWidth);
  46.                 GD.Print($"Initializing chunk at position: {position}"); // Debug print
  47.                 _chunks[index].SetChunkPosition(position);
  48.             }
  49.         }
  50.  
  51.         if (!Engine.IsEditorHint())
  52.         {
  53.             new Thread(new ThreadStart(ThreadProcess)).Start();
  54.         }
  55.     }
  56.  
  57.     public void UpdateChunkPosition(Chunk chunk, Vector2I currentPosition, Vector2I previousPosition)
  58.     {
  59.         if (_positionToChunk.TryGetValue(previousPosition, out var chunkAtPosition) && chunkAtPosition == chunk)
  60.         {
  61.             _positionToChunk.Remove(previousPosition);
  62.         }
  63.  
  64.         _chunkToPosition[chunk] = currentPosition;
  65.         _positionToChunk[currentPosition] = chunk;
  66.  
  67.         chunk.DetermineNeighbors(_positionToChunk);
  68.     }
  69.  
  70.     public void SetBlock(Vector3I globalPosition, Block block)
  71.     {
  72.         var chunktilePosition = new Vector2I(Mathf.FloorToInt(globalPosition.X / (float)Chunk.dimensions.X), Mathf.FloorToInt(globalPosition.Z / (float)Chunk.dimensions.Z));
  73.         lock (_positionToChunk)
  74.         {
  75.             if(_positionToChunk.TryGetValue(chunktilePosition, out var chunk))
  76.             {
  77.                 chunk.SetBlock((Vector3I)(globalPosition - chunk.GlobalPosition), block);
  78.             }
  79.         }
  80.        
  81.     }
  82.  
  83.     public Dictionary<Vector2I, Chunk> GetChunkMap() => _positionToChunk;
  84.  
  85.     public override void _PhysicsProcess(double delta)
  86.     {
  87.         if(!Engine.IsEditorHint())
  88.         {
  89.             lock (_playerPositionLock)
  90.             {
  91.                 _playerPosition = Player.Instance.GlobalPosition;
  92.             }
  93.         }
  94.        
  95.     }
  96.  
  97.     private void ThreadProcess()
  98.     {
  99.         while (IsInstanceValid(this))
  100.         {
  101.             int playerChunkX, playerChunkZ;
  102.             lock(_playerPositionLock)
  103.             {
  104.                 playerChunkX = Mathf.FloorToInt(_playerPosition.X / Chunk.dimensions.X);
  105.                 playerChunkZ = Mathf.FloorToInt(_playerPosition.Z / Chunk.dimensions.Z);
  106.             }
  107.  
  108.             foreach( var chunk in _chunks)
  109.             {
  110.                 var chunkPosition = _chunkToPosition[chunk];
  111.  
  112.                 var chunkX = chunkPosition.X;
  113.                 var chunkZ = chunkPosition.Y;
  114.  
  115.                 var newChunkX = (int)(Mathf.PosMod(chunkX - playerChunkX + _width / 2, _width) + playerChunkX - _width / 2);
  116.                 var newChunkZ = (int)(Mathf.PosMod(chunkZ - playerChunkZ + _width / 2, _width) + playerChunkZ - _width / 2);
  117.  
  118.                 if (newChunkX != chunkX || newChunkZ != chunkZ)
  119.                 {
  120.                     lock(_positionToChunk)
  121.                     {
  122.                         if (_positionToChunk.ContainsKey(chunkPosition))
  123.                         {
  124.                             _positionToChunk.Remove(chunkPosition);
  125.                         }
  126.  
  127.                         var newPosition = new Vector2I(newChunkX, newChunkZ);
  128.                         _chunkToPosition[chunk] = newPosition;
  129.                         _positionToChunk[newPosition] = chunk;
  130.  
  131.                         chunk.CallDeferred(nameof(Chunk.SetChunkPosition), newPosition);
  132.                     }
  133.  
  134.                     Thread.Sleep(150);
  135.                 }
  136.             }
  137.             Thread.Sleep(150);
  138.         }
  139.     }
  140. }
  141.  
Tags: C# Godot
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement