public WorldController(GameTime time, int width, int height) { Items = new List <Item>(); Effects = new List <Effect>(); Miscellaneous = new List <GameObject>(); GameTime = time; ClearEffectTime = GameTime; ClearEffectTime.AddSeconds(10); SetWorldSize(width, height); ScheduleQueue = new PriorityQueue <ActionGroup>(); CraftingMenu = new CraftingMenu(); Items.Add(new Item(width / 2 - 40, height / 2 - 200, ItemType.Spear, 1)); Miscellaneous.Add(new Campfire(width / 2 - 200, height / 2 - 300)); PictureRenderer = new DefaultPictureRenderer(); EntityController = new EntityController(time.Copy(), width, height); // EntityController adds an entity to its list. Add world level event listeners to the new entity. EntityController.PlayerDied += EntityController_PlayerDied; EntityController.AddGameObject += Controller_AddGameObject; EntityController.RemoveGameObject -= Controller_RemoveGameObject; EntityController.CreateEffect += EntityController_CreateEffect; // Make EntityController spawn new entities to add to the world. EntityController.CreateObjects(new OrderedPair <int>(width / 2, height / 2)); PlantController = new PlantController(); // Plant Controller adds a plant to its list. Add world level event listeners to the new plant. PlantController.AddGameObject += Controller_AddGameObject; PlantController.RemoveGameObject += Controller_AddGameObject; PlantController.CreateObjects(new OrderedPair <int>(width / 2, height / 2)); }
// Update Cycle. // Apply logic updates to everything in the world. public void Update(GameTime time, int mouseX, int mouseY) { GameTime = time; List <GameObject> allObjects = EntityController.Entities .Concat(new GameObject[] { EntityController.House }) .Concat(PlantController.Plants.Select(x => (GameObject)x)) .Concat(Items.Select(x => (GameObject)x)) .Concat(Miscellaneous) .ToList(); if (EntityController.Player.IsAlive) { allObjects.Add(EntityController.Player.BasePerson); } ObjectMesh = new ObjectMesh(Utilities.WorldWidth, Utilities.WorldHeight, gridSize, allObjects); // Send game time and object grid to entity controller to apply decision making and updates. Parallel.Invoke(new Action[] { () => { EntityController.EntityUpdate(GameTime, ObjectMesh, mouseX, mouseY); PlantController.PlantUpdate(GameTime); } }); // --- PickupArea --- // Spawn in pickups in random locations. if (++pickupSpawnCounter > 1000) { SpawnItem(ItemType.Apple); SpawnItem(ItemType.Rock); pickupSpawnCounter = 0; } // Check collisions on Items. Only people can pick up pickups. Stack <Item> clearedItems = new Stack <Item>(); foreach (Item pi in Items) { // O(n) action now. People pickup items, which removes some or all of the value of the pickup. // This part checks all pickups and removes those that have no value left. if (pi.Amount <= 0) { pi.SetPickedUp(); clearedItems.Push(pi); // Stack of pickups to remove. } } // Remove pickups from the list. while (clearedItems.Count > 0) { Item p = clearedItems.Pop(); Items.Remove(p); } // --- ScheduleArea --- // Check the schedule to apply actions. These are global events that are tied to the gametime. while (ScheduleQueue.Length > 0) { ActionGroup group = ScheduleQueue.PopMin(); if (group.time <= time) { // Apply scheduled action to entities. if (group.gameObject is Entity en && group.action is EntityAction ea) { // Entity actions done just once. en.TrySetAction(ea, true); } if (group.gameObject is Plant pl && group.action is PlantAction pa) { //Console.WriteLine("Assigning scheduled action to plant using pattern matching"); pl.TrySetAction(pa); } if (group.gameObject is Effect ef && group.action is EffectAction efa) { //Console.WriteLine("Assigning scheduled action to effect using pattern matching"); ef.TrySetAction(efa); } } else { ScheduleQueue.Insert(group); // Put action group back into the schedule. break; } } // Force clear effects that have expired. if (GameTime > ClearEffectTime) { Effects.Clear(); ClearEffectTime.AddSeconds(10); } }