diff --git a/isometric-park-fna/FNAGame.cs b/isometric-park-fna/FNAGame.cs --- a/isometric-park-fna/FNAGame.cs +++ b/isometric-park-fna/FNAGame.cs @@ -10,6 +10,7 @@ using SpriteFontPlus; using isometricparkfna; using System.Diagnostics; +using static isometricparkfna.TileMap; #if DEBUG using ImGuiNET.SampleProgram.XNA; @@ -42,8 +43,8 @@ private const int height = 640; //new tile stuff - int squaresAcross = 50; - int squaresDown = 50; + int squaresAcross = 150; + int squaresDown = 150; int baseOffsetX = -14; int baseOffsetY = -14; @@ -92,7 +93,7 @@ //gdm.SynchronizeWithVerticalRetrace = false; IsFixedTimeStep = false; - this.simulation = new Simulation(this.squaresAcross, this.squaresDown); + this.simulation = new Simulation(this.squaresAcross, this.squaresDown, 16.66667f*30); foreach (List row in this.simulation.map.cells) { @@ -344,7 +345,7 @@ } - + this.simulation.update(gameTime.ElapsedGameTime); this.original_point = Vector2.Transform(new Vector2(mouseCur.X, mouseCur.Y), Matrix.Invert(camera.get_transformation(GraphicsDevice))); @@ -457,7 +458,7 @@ SpriteEffects.None, depth); } - + } diff --git a/isometric-park-fna/Simulation.cs b/isometric-park-fna/Simulation.cs --- a/isometric-park-fna/Simulation.cs +++ b/isometric-park-fna/Simulation.cs @@ -1,4 +1,5 @@ using System; +using static isometricparkfna.TileMap; namespace isometricparkfna { @@ -15,6 +16,13 @@ private set; } + public float Elapsed + { + get; + + private set; + } + public DateTime DateTime { get; @@ -24,21 +32,80 @@ public decimal money; + public float millisecondsPerAdvance { get; private set; } + public TileMap map; - public Simulation(int width, int height) + public int ticksPerAdvance; + + private float lastAdvance; + + public Simulation(int width, int height, float millisecondsPerAdvance) { this.DateTime = new DateTime(START_YEAR, START_MONTH, START_DAY); this.map = new TileMap(width, height); this.money = 1000; + this.millisecondsPerAdvance = millisecondsPerAdvance; } - public void advanceClock() + private void advanceSimulation() { - this.Tick++; + Random random = new Random(); + this.DateTime = this.DateTime.AddMonths(1); + + foreach (Cell cell in this.map.iterate_cells()) + { + if (random.NextDouble() > 0.9995f) + { + cell.hasTree = true; + } + } + + foreach (Cell cell in this.map.iterate_cells_with_neighbors(4)) + { + if (random.NextDouble() > 0.995f) + { + cell.hasTree = true; + } + } - this.DateTime.AddMonths(1); + foreach (Cell cell in this.map.iterate_cells_with_neighbors(7)) + { + if (random.NextDouble() > 0.995f) + { + cell.hasTree = false; + } + } + } + public void update(TimeSpan deltaTime) + { + //this.Tick++; + + this.Elapsed += deltaTime.Milliseconds; + + int advancesToSimulate = (int)((this.Elapsed - this.lastAdvance) / this.millisecondsPerAdvance); + + for (int i = 0; i < advancesToSimulate; i++) + { + this.advanceSimulation(); + + //Partial frames haven't been simulated so they're not counted as part of + //lastAdvance + //Example: + //We start at t=100 and simulate every 10 t. If we miss enough updates that + //it's t=125, we have 2.5 steps to simulate. However, we only want to simulate + //whole steps, so that means we'll simulate 2. But that means we've only simulated + //through t=120, so that's what we want to track in lastAdvance. + this.lastAdvance += advancesToSimulate * this.millisecondsPerAdvance; + } + + /* + if ((this.Tick % this.millisecondsPerAdvance) == 0) + { + this.DateTime = this.DateTime.AddMonths(1); + }*/ + } } diff --git a/isometric-park-fna/TileMap.cs b/isometric-park-fna/TileMap.cs --- a/isometric-park-fna/TileMap.cs +++ b/isometric-park-fna/TileMap.cs @@ -90,16 +90,84 @@ { foreach (Cell cell in row) { - yield return cell; + yield return cell; } } } - - } + public Boolean inBounds(int x, int y) + { + return MathUtils.Between(x, 0, MapWidth - 1) && MathUtils.Between(y, 0, MapHeight - 1); + } - public class Cell - { - public Boolean hasTree = false; + private System.Collections.IEnumerable iterate_neighbors(int x, int y) + { + //iterates over neighbors (clockwise starting at noon/midnight) + if (inBounds(x, y + 1)) + { + yield return this.cells[x - 1][y]; + } + if (inBounds(x + 1, y + 1)) + { + yield return this.cells[x + 1][y + 1]; + } + if (inBounds(x + 1, y)) + { + yield return this.cells[x + 1][y]; + } + if (inBounds(x + 1, y - 1)) + { + yield return this.cells[x + 1][y - 1]; + } + if (inBounds(x, y - 1)) + { + yield return this.cells[x][y - 1]; + } + if (inBounds(x - 1, y-1)) + { + yield return this.cells[x - 1][y-1]; + } + if (inBounds(x - 1, y)) + { + yield return this.cells[x - 1][y]; + } + if (inBounds(x - 1, y + 1)) + { + yield return this.cells[x - 1][y+1]; + } + } + + private int countNeighbors(int x, int y) + { + int count = 0; + foreach (Cell neighbor in this.iterate_neighbors(x, y)) + { + count++; + } + + return count; + } + + public System.Collections.IEnumerable iterate_cells_with_neighbors(int neighbors) + { + for (int i = 0; i < MapHeight; i++) + { + List newRow = new List(); + for (int j = 0; j < MapWidth; j++) + { + if (this.countNeighbors(i, j) >= neighbors) + { + yield return cells[i][j]; + } + } + } + + + } + + public class Cell + { + public Boolean hasTree = false; + } } -} +} \ No newline at end of file