using System; using FOU.Scripts.Elements; using Godot; namespace FOU.Scripts; public class Level { public Vector2I Resolution; private Chunk[,] chunks; private Image image; private int chunksX; private int chunksY; // per chunk: private int chunkResX; private int chunkResY; private float rainAmount = 0; public Level(Main main, int sizeX, int sizeY) { Resolution = new Vector2I(sizeX, sizeY); chunksX = main.ChunksPerAxis; chunksY = main.ChunksPerAxis; chunkResX = sizeX / chunksX; chunkResY = sizeY / chunksY; GD.Print($"Generating level ({sizeX}:{sizeY}) with {chunksX*chunksY} chunks ({chunkResX} * {chunkResY})"); image = Image.Create(sizeX, sizeY, false, Image.Format.Rgb8); chunks = new Chunk[chunksX, chunksY]; int index = 0; // create all chunks for (int x = 0; x < chunksX; x++) { for (int y = 0; y < chunksY; y++) { chunks[x, y] = new Chunk(chunkResX, chunkResY, index++); } } // assign neighbors for (int x = 0; x < chunksX; x++) { for (int y = 0; y < chunksY; y++) { if (y > 0) chunks[x, y].NeighborN = chunks[x, y-1]; if (y < chunksY-1) chunks[x, y].NeighborS = chunks[x, y+1]; if (x > 0) chunks[x, y].NeighborE = chunks[x-1, y]; if (x < chunksX-1) chunks[x, y].NeighborW = chunks[x+1, y]; } } } public void Update() { MakeItRain(); foreach (Chunk c in chunks) c.Update(); } public void SetRainAmount(float amount) { rainAmount = amount; } public void StartBenchmark() { GD.Print("benchmark"); for (int x = 0; x < chunksX; x++) { for (int y = 0; y < chunksY; y++) { chunks[x, y].WritePixel(chunkResX/2, chunkResY/2, 100); } } } public Chunk[,] GetChunks() { return chunks; } private void MakeItRain() { if (rainAmount < .1f) return; int rainDrops = (int)Math.Round(rainAmount); for (int i = 0; i <= rainDrops; i++) { if (GD.Randf() < rainAmount) WritePixel((int)(GD.Randi() % (chunkResX * chunksX)), 0, 1); } } public void WritePixel(int x, int y, int size) { chunks[x/chunkResX, y/chunkResY].WritePixel(x % chunkResX, y % chunkResY, size); } public Image DrawLevel() { for (int cx = 0; cx < chunksX; cx++) { for (int cy = 0; cy < chunksY; cy++) { for (int x = 0; x < chunkResX; x++) { for (int y = 0; y < chunkResY; y++) { // TODO: multithreading here! use Chunk.DrawLevel() and stitch images together image.SetPixel(cx*chunkResX + x, cy*chunkResY + y, chunks[cx,cy].Elements[x, y].Color); } } } } return image; } }