#region File Description //----------------------------------------------------------------------------- // GameplayScreen.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using System.Threading; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using GameStateManagement; #endregion namespace GameStateManagementSample { /// /// This screen implements the actual game logic. It is just a /// placeholder to get the idea across: you'll probably want to /// put some more interesting gameplay in here! /// class GameplayScreen : GameScreen { #region Fields ContentManager content; SpriteFont gameFont; Vector2 playerPosition = new Vector2(100, 100); Vector2 enemyPosition = new Vector2(100, 100); Random random = new Random(); float pauseAlpha; InputAction pauseAction; #endregion #region Initialization /// /// Constructor. /// public GameplayScreen() { TransitionOnTime = TimeSpan.FromSeconds(1.5); TransitionOffTime = TimeSpan.FromSeconds(0.5); pauseAction = new InputAction( new Buttons[] { Buttons.Start, Buttons.Back }, new Keys[] { Keys.Escape }, true); } /// /// Load graphics content for the game. /// public override void Activate(bool instancePreserved) { if (!instancePreserved) { if (content == null) content = new ContentManager(ScreenManager.Game.Services, "Content"); gameFont = content.Load("gamefont"); // A real game would probably have more content than this sample, so // it would take longer to load. We simulate that by delaying for a // while, giving you a chance to admire the beautiful loading screen. Thread.Sleep(1000); // once the load has finished, we use ResetElapsedTime to tell the game's // timing mechanism that we have just finished a very long frame, and that // it should not try to catch up. ScreenManager.Game.ResetElapsedTime(); } #if WINDOWS_PHONE if (Microsoft.Phone.Shell.PhoneApplicationService.Current.State.ContainsKey("PlayerPosition")) { playerPosition = (Vector2)Microsoft.Phone.Shell.PhoneApplicationService.Current.State["PlayerPosition"]; enemyPosition = (Vector2)Microsoft.Phone.Shell.PhoneApplicationService.Current.State["EnemyPosition"]; } #endif } public override void Deactivate() { #if WINDOWS_PHONE Microsoft.Phone.Shell.PhoneApplicationService.Current.State["PlayerPosition"] = playerPosition; Microsoft.Phone.Shell.PhoneApplicationService.Current.State["EnemyPosition"] = enemyPosition; #endif base.Deactivate(); } /// /// Unload graphics content used by the game. /// public override void Unload() { content.Unload(); #if WINDOWS_PHONE Microsoft.Phone.Shell.PhoneApplicationService.Current.State.Remove("PlayerPosition"); Microsoft.Phone.Shell.PhoneApplicationService.Current.State.Remove("EnemyPosition"); #endif } #endregion #region Update and Draw /// /// Updates the state of the game. This method checks the GameScreen.IsActive /// property, so the game will stop updating when the pause menu is active, /// or if you tab away to a different application. /// public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen) { base.Update(gameTime, otherScreenHasFocus, false); // Gradually fade in or out depending on whether we are covered by the pause screen. if (coveredByOtherScreen) pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1); else pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0); if (IsActive) { // Apply some random jitter to make the enemy move around. const float randomization = 10; enemyPosition.X += (float)(random.NextDouble() - 0.5) * randomization; enemyPosition.Y += (float)(random.NextDouble() - 0.5) * randomization; // Apply a stabilizing force to stop the enemy moving off the screen. Vector2 targetPosition = new Vector2( ScreenManager.GraphicsDevice.Viewport.Width / 2 - gameFont.MeasureString("Insert Gameplay Here").X / 2, 200); enemyPosition = Vector2.Lerp(enemyPosition, targetPosition, 0.05f); // TODO: this game isn't very fun! You could probably improve // it by inserting something more interesting in this space :-) } } /// /// Lets the game respond to player input. Unlike the Update method, /// this will only be called when the gameplay screen is active. /// public override void HandleInput(GameTime gameTime, InputState input) { if (input == null) throw new ArgumentNullException("input"); // Look up inputs for the active player profile. int playerIndex = (int)ControllingPlayer.Value; KeyboardState keyboardState = input.CurrentKeyboardStates[playerIndex]; GamePadState gamePadState = input.CurrentGamePadStates[playerIndex]; // The game pauses either if the user presses the pause button, or if // they unplug the active gamepad. This requires us to keep track of // whether a gamepad was ever plugged in, because we don't want to pause // on PC if they are playing with a keyboard and have no gamepad at all! bool gamePadDisconnected = !gamePadState.IsConnected && input.GamePadWasConnected[playerIndex]; PlayerIndex player; if (pauseAction.Evaluate(input, ControllingPlayer, out player) || gamePadDisconnected) { #if WINDOWS_PHONE ScreenManager.AddScreen(new PhonePauseScreen(), ControllingPlayer); #else ScreenManager.AddScreen(new PauseMenuScreen(), ControllingPlayer); #endif } else { // Otherwise move the player position. Vector2 movement = Vector2.Zero; if (keyboardState.IsKeyDown(Keys.Left)) movement.X--; if (keyboardState.IsKeyDown(Keys.Right)) movement.X++; if (keyboardState.IsKeyDown(Keys.Up)) movement.Y--; if (keyboardState.IsKeyDown(Keys.Down)) movement.Y++; Vector2 thumbstick = gamePadState.ThumbSticks.Left; movement.X += thumbstick.X; movement.Y -= thumbstick.Y; if (input.TouchState.Count > 0) { Vector2 touchPosition = input.TouchState[0].Position; Vector2 direction = touchPosition - playerPosition; direction.Normalize(); movement += direction; } if (movement.Length() > 1) movement.Normalize(); playerPosition += movement * 8f; } } /// /// Draws the gameplay screen. /// public override void Draw(GameTime gameTime) { // This game has a blue background. Why? Because! ScreenManager.GraphicsDevice.Clear(ClearOptions.Target, Color.CornflowerBlue, 0, 0); // Our player and enemy are both actually just text strings. SpriteBatch spriteBatch = ScreenManager.SpriteBatch; spriteBatch.Begin(); spriteBatch.DrawString(gameFont, "// TODO", playerPosition, Color.Green); spriteBatch.DrawString(gameFont, "Insert Gameplay Here", enemyPosition, Color.DarkRed); spriteBatch.End(); // If the game is transitioning on or off, fade it out to black. if (TransitionPosition > 0 || pauseAlpha > 0) { float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2); ScreenManager.FadeBackBufferToBlack(alpha); } } #endregion } }