/// <summary> /// Spawn a power-up based on the data in the packet. /// </summary> private void SpawnPowerup() { int whichPowerUp = packetReader.ReadInt32(); if (powerUp == null) { switch (whichPowerUp) { case 0: powerUp = new DoubleLaserPowerUp(); break; case 1: powerUp = new TripleLaserPowerUp(); break; case 2: powerUp = new RocketPowerUp(); break; } } if (powerUp != null) { powerUp.Position = packetReader.ReadVector2(); powerUp.Initialize(); } }
/// <summary> /// Update the world. /// </summary> /// <param name="elapsedTime">The amount of elapsed time, in seconds.</param> /// <param name="paused">If true, the game is paused.</param> public void Update(float elapsedTime, bool paused) { if (gameWon) { // update the particle-effect manager particleEffectManager.Update(elapsedTime); // make sure the collision manager is empty CollisionManager.Collection.ApplyPendingRemovals(); if (CollisionManager.Collection.Count > 0) { CollisionManager.Collection.Clear(); } } else { // process all incoming packets ProcessPackets(); // if the game is in progress, update the state of it if (initialized && (networkSession != null) && (networkSession.SessionState == NetworkSessionState.Playing)) { // presence support int highScore = int.MinValue; int highScoreIndex = -1; for (int i = 0; i < networkSession.AllGamers.Count; i++) { NetworkGamer networkGamer = networkSession.AllGamers[i]; PlayerData playerData = networkGamer.Tag as PlayerData; if ((playerData != null) && (playerData.Ship != null)) { int playerScore = playerData.Ship.Score; if (playerScore == highScore) { highScorers.Add(i); } else if (playerScore > highScore) { highScorers.Clear(); highScorers.Add(i); highScore = playerScore; highScoreIndex = i; } } } // the host has singular responsibilities to the game world, // that need to be done once, by one authority if (networkSession.IsHost) { // get the local player, for frequent re-use LocalNetworkGamer localGamer = networkSession.Host as LocalNetworkGamer; // check for victory // if victory has been achieved, send a packet to everyone if (highScore >= winningScore) { packetWriter.Write((int)PacketTypes.GameWon); packetWriter.Write(highScoreIndex); localGamer.SendData(packetWriter, SendDataOptions.ReliableInOrder); } // respawn each player, if it is time to do so for (int i = 0; i < networkSession.AllGamers.Count; i++) { NetworkGamer networkGamer = networkSession.AllGamers[i]; PlayerData playerData = networkGamer.Tag as PlayerData; if ((playerData != null) && (playerData.Ship != null) && !playerData.Ship.Active && (playerData.Ship.RespawnTimer <= 0f)) { // write the ship-spawn packet packetWriter.Write((int)PacketTypes.ShipSpawn); packetWriter.Write(i); packetWriter.Write(CollisionManager.FindSpawnPoint( playerData.Ship, playerData.Ship.Radius)); localGamer.SendData(packetWriter, SendDataOptions.ReliableInOrder); } } // respawn the power-up if it is time to do so if (powerUp == null) { powerUpTimer -= elapsedTime; if (powerUpTimer < 0) { // write the power-up-spawn packet packetWriter.Write((int)PacketTypes.PowerUpSpawn); packetWriter.Write(RandomMath.Random.Next(3)); packetWriter.Write(CollisionManager.FindSpawnPoint(null, PowerUp.PowerUpRadius * 3f)); localGamer.SendData(packetWriter, SendDataOptions.ReliableInOrder); } } else { powerUpTimer = maximumPowerUpTimer; } // send everyone an update on the state of the world if (updatesSinceWorldDataSend >= updatesBetweenWorldDataSend) { packetWriter.Write((int)PacketTypes.WorldData); // write each of the asteroids for (int i = 0; i < asteroids.Length; i++) { packetWriter.Write(asteroids[i].Position); packetWriter.Write(asteroids[i].Velocity); } localGamer.SendData(packetWriter, SendDataOptions.InOrder); updatesSinceWorldDataSend = 0; } else { updatesSinceWorldDataSend++; } } // update each asteroid foreach (Asteroid asteroid in asteroids) { if (asteroid.Active) { asteroid.Update(elapsedTime); } } // update the power-up if (powerUp != null) { if (powerUp.Active) { powerUp.Update(elapsedTime); } else { powerUp = null; } } // process the local player's input if (!paused) { ProcessLocalPlayerInput(); } // update each ship foreach (NetworkGamer networkGamer in networkSession.AllGamers) { PlayerData playerData = networkGamer.Tag as PlayerData; if ((playerData != null) && (playerData.Ship != null)) { if (playerData.Ship.Active) { playerData.Ship.Update(elapsedTime); // check for death // -- only check on local machines - the local player is // the authority on the death of their own ship if (networkGamer.IsLocal && (playerData.Ship.Life < 0)) { SendLocalShipDeath(); } } else if (playerData.Ship.RespawnTimer > 0f) { playerData.Ship.RespawnTimer -= elapsedTime; if (playerData.Ship.RespawnTimer < 0f) { playerData.Ship.RespawnTimer = 0f; } } } } // update the other players with the current state of the local ship if (updatesSinceStatusPacket >= updatesBetweenStatusPackets) { updatesSinceStatusPacket = 0; SendLocalShipData(); } else { updatesSinceStatusPacket++; } // update the collision manager CollisionManager.Update(elapsedTime); // update the particle-effect manager particleEffectManager.Update(elapsedTime); } } }