/// <summary> /// Creates randomly sized and positioned rooms with no overlaps. Rooms are odd sized and odd centered. /// </summary> private void GenerateRooms() { List <CollisionRectangle> roomRectangles = new List <CollisionRectangle>(); for (int i = 0; i < ROOM_ATTEMPTS; i++) { // ensure room dimensions are odd int size = rng.Next(1, 3) * 2 + 1; int width = size; int height = size; // make the room less perfect if (rng.Next(0, 2) == 0) { width += 2 * rng.Next(0, 1 + size / 2); } else { height += 2 * rng.Next(0, 1 + size / 2); } // align room with odd coordinate int x = rng.Next(0, MAX_HEIGHT / 2) * 2 + 1; int y = rng.Next(0, MAX_WIDTH / 2) * 2 + 1; Rectangle room = new Rectangle(x, y, width, height); if (collisionTree.GetCollisions(room, roomRectangles).Count != 0) { continue; } if (room.X + room.Width >= MAX_WIDTH || room.Y + room.Height >= MAX_HEIGHT) { continue; } // Adding rooms rooms.Add(room); roomRectangles.Add(new CollisionRectangle(room)); currentRegion++; for (int j = room.X; j <= room.X + room.Width; j++) { for (int k = room.Y; k <= room.Y + room.Height; k++) { region[j, k] = currentRegion; } } } }
/// <summary> /// Update subprogram for <see cref="World"/> /// </summary> /// <param name="gameTime">Provides a snapshot of timing values</param> public void Update(GameTime gameTime) { // Shifting chunk and loading chunks if needed, if current chunk is not centered if (Player.Instance.CurrentChunk != loadedChunks[CHUNK_COUNT / 2, CHUNK_COUNT / 2].Position) { AdjustLoadedChunks(Player.Instance.CurrentChunk); } // Updating current building if inside a building if (IsInside) { CurrentBuilding.Update(gameTime); } // Generating enemies every 3s enemyGenerationTimer += gameTime.ElapsedGameTime.Milliseconds / 1000.0f; if (enemyGenerationTimer > ENEMY_GENERATE_TIME) { chunkBounaryID = SharedData.RNG.Next(chunkBoundaries.Length); if (!GetTileAt(chunkBoundaries[chunkBounaryID] + Player.Instance.CurrentChunk).OutsideObstructState) { enemies.Add(Enemy.RandomEnemy(chunkBoundaries[chunkBounaryID] + Player.Instance.CurrentTile, false)); } enemyGenerationTimer = 0; } // Updating enemies if (!IsInside) { for (int i = enemies.Count - 1; i >= 0; --i) { enemies[i].Update(gameTime); // Removing enemies if they die and giving player corresponding loot if (!enemies[i].Alive) { Player.Instance.Experience += enemies[i].Experience; Player.Instance.Gold += enemies[i].Gold; AddItems(enemies[i].HitBox, enemies[i].LootTable); enemies.RemoveAt(i); } } } else { // Updating dungeon enemies for (int i = DungeonEnemies.Count - 1; i >= 0; --i) { DungeonEnemies[i].Update(gameTime); // Removing enemies if they die and giving player corresponding loot if (!DungeonEnemies[i].Alive) { Player.Instance.Experience += DungeonEnemies[i].Experience; Player.Instance.Gold += DungeonEnemies[i].Gold; AddItems(DungeonEnemies[i].HitBox, DungeonEnemies[i].LootTable); DungeonEnemies.RemoveAt(i); } } } // Updating the projectiles and collision info in the world for (int i = projectiles.Count - 1; i >= 0; --i) { projectiles[i].Update(gameTime); // Removing projectiles if they are not active if (!projectiles[i].Active) { projectiles.RemoveAt(i); continue; } // Inflicting damage and removing projectile if it hits a enemy if (IsInside) { hitEnemies.AddRange(collisionTree.GetCollisions(projectiles[i].HitBox, DungeonEnemies)); } else { hitEnemies = collisionTree.GetCollisions(projectiles[i].HitBox, enemies); } // Inflicting damage on enemies that are hit by the projectile and removing the projectile for (int j = 0; j < hitEnemies.Count; ++j) { hitEnemies[j].Health -= projectiles[i].DamageAmount; } if (hitEnemies.Count > 0) { projectiles.RemoveAt(i); } } // Updating live items for (int i = liveItems.Count - 1; i >= 0; --i) { liveItems[i].Update(gameTime); // Removing item if it despawns if (!liveItems[i].Live) { liveItems.RemoveAt(i); } } // Removing enemies outside of the loaded world for (int i = enemies.Count - 1; i >= 0; --i) { if (!worldBoundsRect.Contains(enemies[i].HitBox)) { enemies.RemoveAt(i); } } }