diff --git a/src/Game1.cs b/src/Game1.cs index 061b2b7..00f6c75 100644 --- a/src/Game1.cs +++ b/src/Game1.cs @@ -1,13 +1,15 @@ -using Microsoft.Xna.Framework; +using System.Collections.Generic; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; - +using World; namespace tunnet; public class Game1 : Game { private GraphicsDeviceManager _graphics; private SpriteBatch _spriteBatch; + private Dictionary _chunks; public Game1() { @@ -19,6 +21,7 @@ public class Game1 : Game protected override void Initialize() { // TODO: Add your initialization logic here + _chunks = new Dictionary(); base.Initialize(); } diff --git a/src/src/World.cs b/src/src/World.cs new file mode 100644 index 0000000..65ea2ed --- /dev/null +++ b/src/src/World.cs @@ -0,0 +1,129 @@ +using System.Collections.Generic; +using System.IO; +using Microsoft.Xna.Framework; +// +namespace World; + +public class Tile +{ + public int Id { get; } + public Tile(int id) => Id = id; + public static Tile FromId(int id) => new Tile(id); +} +public class Chunk +{ + public const int Width = 16; + public const int Height = 16; + public Tile[,] Tiles { get; private set; } + + public Chunk() + { + Tiles = new Tile[Width, Height]; + } +} + +public static class ChunkStorage +{ + /// + /// Saves the given chunk to disk in a compact binary format: + /// Width×Height consecutive Int32 tile IDs. + /// + public static void Save(string filePath, Chunk chunk) + { + if (chunk == null) + throw new System.ArgumentNullException(nameof(chunk)); + + Directory.CreateDirectory(Path.GetDirectoryName(filePath) ?? "."); + using var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write); + using var writer = new BinaryWriter(fs); + + for (int x = 0; x < Chunk.Width; x++) + { + for (int y = 0; y < Chunk.Height; y++) + { + // write each tile’s ID + writer.Write(chunk.Tiles[x, y]?.Id ?? 0); + } + } + } + public static void Save(int chunkX, int chunkY, Chunk chunk) + { + Save($"{chunkX}_{chunkY}.chunk", chunk); + } + + /// + /// Loads a chunk from the binary file format produced by Save(). + /// + public static Chunk Load(string filePath) + { + if (!File.Exists(filePath)) + throw new FileNotFoundException("Chunk file not found", filePath); + + var chunk = new Chunk(); + using var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); + using var reader = new BinaryReader(fs); + + for (int x = 0; x < Chunk.Width; x++) + for (int y = 0; y < Chunk.Height; y++) + { + int id = reader.ReadInt32(); + chunk.Tiles[x, y] = Tile.FromId(id); + } + + return chunk; + } + public static Chunk Load(int chunkX, int chunkY) + { + var filePath = $"{chunkX}_{chunkY}.chunk"; + if (File.Exists(filePath)) + return Load(filePath); + return null; + } +} +public class WorldMap +{ + private readonly Dictionary _loadedChunks = new Dictionary(); + + // Get a chunk (load if not in memory) + public Chunk GetChunk(int chunkX, int chunkY) + { + var key = new Point(chunkX, chunkY); + if (!_loadedChunks.TryGetValue(key, out Chunk chunk)) + { + chunk = ChunkStorage.Load(chunkX, chunkY);// LoadChunkFromDisk(chunkX, chunkY); // Or generate + _loadedChunks[key] = chunk; + } + return chunk; + } + + // Access a specific tile + public Tile GetTile(int worldX, int worldY) + { + int chunkX = worldX / Chunk.Width; + int chunkY = worldY / Chunk.Height; + int tileX = worldX % Chunk.Width; + int tileY = worldY % Chunk.Height; + + // Handle negative coordinates + if (tileX < 0) tileX += Chunk.Width; + if (tileY < 0) tileY += Chunk.Height; + + return GetChunk(chunkX, chunkY).Tiles[tileX, tileY]; + } + + // Unload distant chunks (memory management) + public void UnloadChunks(Point currentChunk, int keepRadius) + { + var keysToRemove = new List(); + foreach (var key in _loadedChunks.Keys) + { + if (System.Math.Abs(key.X - currentChunk.X) > keepRadius || + System.Math.Abs(key.Y - currentChunk.Y) > keepRadius) + { + ChunkStorage.Save(key.X, key.Y, _loadedChunks[key]); // Persist if needed + keysToRemove.Add(key); + } + } + keysToRemove.ForEach(k => _loadedChunks.Remove(k)); + } +} \ No newline at end of file