// Runs the in game update for objets that need to save state public HashSet <Sprite> Update(KeyboardState kstate, GameTime gameTime, Camera camera) { List <Sprite> toRemove = new List <Sprite>(); HashSet <Sprite> droppedItemObjectUpdateOrder = new HashSet <Sprite>(); // camera follows player if (!player.onShip || player.playerInInterior != null) { camera.Position = player.location; } else { camera.Position = player.playerOnShip.location; } // add any dropped/onGround items in the world (and placable items) foreach (var item in ItemUtility.ItemsToUpdate) { droppedItemObjectUpdateOrder.Add(item); } HashSet <Sprite> fullOrder = UpdateOrder; fullOrder.UnionWith(droppedItemObjectUpdateOrder); foreach (Sprite sp in fullOrder) { if (sp.remove) { toRemove.Add(sp); ItemUtility.ItemsToUpdate.Remove(sp); } // ICanUpdate is the update for main sprites. Any sub-sprites (items, weapons, sails, etc) that belong to the main sprite are updated within the sprite's personal update method. ICanUpdate updateSp = (ICanUpdate)sp; updateSp.Update(kstate, gameTime, camera); } // keep updates running for anything(non player) in an interior foreach (Interior inside in BoundingBoxLocations.interiorMap.Values) { inside.Update(kstate, gameTime, camera); } // clear any "dead" or picked up objects from updating foreach (var r in toRemove) { fullOrder.Remove(r); } return(fullOrder); }
public void Update(KeyboardState kstate, GameTime gameTime, Camera camera) { HashSet <Sprite> toRemove = new HashSet <Sprite>(); // add any dropped objects to the interior foreach (var dropped in interiorObjectsToAdd) { interiorObjects.Add(dropped); } interiorObjectsToAdd.Clear(); foreach (var obj in interiorObjects) { obj.inInteriorId = interiorId; if (obj.remove) { toRemove.Add(obj); } // match speed of interior (for ships) obj.location.X += speed.X; obj.location.Y += speed.Y; if (obj is ICanUpdate && !(obj is IPlayer)) // let gamestate update the player { ICanUpdate updateSp = (ICanUpdate)obj; updateSp.Update(kstate, gameTime, camera); } } foreach (var remove in toRemove) { remove.inInteriorId = Guid.Empty; interiorObjects.Remove(remove); } }
/// <summary> ESSENTIALLY THE USER INPUT AND PHYSICS DETAILS /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { var kstate = Keyboard.GetState(); HashSet <Sprite> groundObjectUpdateOrder = new HashSet <Sprite>(); if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.F4)) { Exit(); } if (kstate.IsKeyDown(Keys.F12)) { gameState.SaveGameState(); Exit(); } // game menu before everything if (startingMenu.showMenu) { startingMenu.Update(kstate, gameTime); return; } else if (startingMenu.selected == "new" && !gameState.ready) { gameState.CreateNewGame(); return; } else if (startingMenu.selected == "load" && !gameState.ready) { gameState.LoadGameState(); return; } // weather weather.Update(kstate, gameTime); // daylight shader dayLight.Update(kstate, gameTime); // static update (Menus) windArrows.Update(kstate, gameTime, null); int windDirection = windArrows.getWindDirection(); int windSpeed = windArrows.getWindSpeed(); inventoryMenu.Update(kstate, gameTime, this.camera); craftingMenu.Update(kstate, gameTime, this.camera); Collidable.Clear(); DrawOrder.Clear(); // set any viewport visible(and not visible when in interior) collidable map pieces for collision - update LandTileLocList and GroundObjLocList BoundingBoxLocations.LandTileLocationList.Clear(); BoundingBoxLocations.OceanTileLocationList.Clear(); BoundingBoxLocations.GroundObjectLocationList.Clear(); BoundingBoxLocations.TilesInView.Clear(); Vector2 minCorner = new Vector2(camera.Position.X - (GameOptions.PrefferedBackBufferWidth / 2), camera.Position.Y - (GameOptions.PrefferedBackBufferHeight / 2)); Vector2 maxCorner = new Vector2(camera.Position.X + (GameOptions.PrefferedBackBufferWidth / 2), camera.Position.Y + (GameOptions.PrefferedBackBufferHeight / 2)); foreach (var tp in GameMapTiles.map) { if ((tp.location.X >= (minCorner.X - GameOptions.tileWidth) && tp.location.X <= (maxCorner.X + GameOptions.tileWidth)) && (tp.location.Y >= (minCorner.Y - GameOptions.tileHeight) && tp.location.Y <= (maxCorner.Y + GameOptions.tileHeight))) { BoundingBoxLocations.TilesInView.Add(tp); if (tp.bbKey.Equals("landTile")) { BoundingBoxLocations.LandTileLocationList.Add(tp); SpatialBounding.SetQuad(tp.GetBase()); } else { BoundingBoxLocations.OceanTileLocationList.Add(tp); } if (tp.groundObjects != null) { foreach (var groundObject in tp.groundObjects) { if (!groundObject.remove) { BoundingBoxLocations.GroundObjectLocationList.Add(groundObject); } else { if (groundObject is IGroundObject) { IGroundObject go = (IGroundObject)groundObject; go.UpdateRespawn(gameTime); } } } } } } BoundingBoxLocations.InteriorTileList.Clear(); // set interior for collision for the interior that the player is in if (gameState.player.playerInInterior != null) { // interior tiles for collision foreach (var tile in gameState.player.playerInInterior.interiorTiles) { BoundingBoxLocations.InteriorTileList.Add(tile); SpatialBounding.SetQuad(tile.GetBase()); } // TODO: update the interior objects for collision (only do this when player is in there) foreach (var obj in gameState.player.playerInInterior.interiorObjects) { SpatialBounding.SetQuad(obj.GetBase()); Collidable.Add(obj); } } Vector2 lastCamPos = camera.Position; // update any gameObjects that need to track state (will set camera pos to player) HashSet <Sprite> GameStateObjectUpdateOrder = gameState.Update(kstate, gameTime, camera); // use this to offset water noise camMove.X = ((camera.Position.X % GameOptions.PrefferedBackBufferWidth) / (GameOptions.PrefferedBackBufferWidth)); camMove.Y = ((camera.Position.Y % GameOptions.PrefferedBackBufferHeight) / (GameOptions.PrefferedBackBufferHeight)); // update ground objects (they do not track their state since they are encoded in the map) foreach (var sp in BoundingBoxLocations.GroundObjectLocationList) { ICanUpdate updateSp = (ICanUpdate)sp; updateSp.Update(kstate, gameTime, this.camera); groundObjectUpdateOrder.Add(sp); } // merge update orders HashSet <Sprite> fullUpdateOrder = GameStateObjectUpdateOrder; fullUpdateOrder.UnionWith(groundObjectUpdateOrder); // Set draw order and collision from the full update order list foreach (var sp in fullUpdateOrder) { if (gameState.player.playerInInterior != null) { // only add ships and land tiles when to collision when interior is being viewed if (sp is IShip || sp is ITilePiece || sp is IPlayer) { sp.SetBoundingBox(); Collidable.Add(sp); SpatialBounding.SetQuad(sp.GetBase()); } } else { Collidable.Add(sp); SpatialBounding.SetQuad(sp.GetBase()); DrawOrder.Add(sp); } } // handle collision collision.Update(this.camera.Position); SpatialCollision(); this.camera.Update(gameTime); base.Update(gameTime); }