| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- #region File Description
- //-----------------------------------------------------------------------------
- // Game.cs
- //
- // Microsoft XNA Community Game Platform
- // Copyright (C) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- #endregion
- #region Using Statements
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Content;
- using Microsoft.Xna.Framework.Graphics;
- using Microsoft.Xna.Framework.Input;
- using System;
- #endregion
- namespace ChaseCameraSample
- {
- /// <summary>
- /// Sample showing how to implement a simple chase camera.
- /// </summary>
- public class ChaseCameraGame : Microsoft.Xna.Framework.Game
- {
- #region Fields
- GraphicsDeviceManager graphics;
- SpriteBatch spriteBatch;
- SpriteFont spriteFont;
- KeyboardState lastKeyboardState = new KeyboardState();
- GamePadState lastGamePadState = new GamePadState();
- MouseState lastMousState = new MouseState();
- KeyboardState currentKeyboardState = new KeyboardState();
- GamePadState currentGamePadState = new GamePadState();
- MouseState currentMouseState = new MouseState();
- Ship ship;
- ChaseCamera camera;
- Model shipModel;
- Model groundModel;
- bool cameraSpringEnabled = true;
- #endregion
- #region Initialization
- public ChaseCameraGame()
- {
- graphics = new GraphicsDeviceManager(this);
- graphics.SupportedOrientations = DisplayOrientation.Portrait;
-
-
- Content.RootDirectory = "Content";
- IsMouseVisible = true;
- #if WINDOWS_PHONE
- graphics.PreferredBackBufferWidth = 480;
- graphics.PreferredBackBufferHeight = 800;
-
- TargetElapsedTime = TimeSpan.FromTicks(333333);
- graphics.IsFullScreen = true;
- #else
- graphics.PreferredBackBufferWidth = 853;
- graphics.PreferredBackBufferHeight = 480;
- #endif
- // Create the chase camera
- camera = new ChaseCamera();
- // Set the camera offsets
- camera.DesiredPositionOffset = new Vector3(0.0f, 2000.0f, 3500.0f);
- camera.LookAtOffset = new Vector3(0.0f, 150.0f, 0.0f);
- // Set camera perspective
- camera.NearPlaneDistance = 10.0f;
- camera.FarPlaneDistance = 100000.0f;
- //TODO: Set any other camera invariants here such as field of view
- }
- /// <summary>
- /// Initalize the game
- /// </summary>
- protected override void Initialize()
- {
- base.Initialize();
- ship = new Ship(GraphicsDevice);
- // Set the camera aspect ratio
- // This must be done after the class to base.Initalize() which will
- // initialize the graphics device.
- camera.AspectRatio = (float)graphics.GraphicsDevice.Viewport.Width /
- graphics.GraphicsDevice.Viewport.Height;
- // Perform an inital reset on the camera so that it starts at the resting
- // position. If we don't do this, the camera will start at the origin and
- // race across the world to get behind the chased object.
- // This is performed here because the aspect ratio is needed by Reset.
- UpdateCameraChaseTarget();
- camera.Reset();
- }
- /// <summary>
- /// Load graphics content.
- /// </summary>
- protected override void LoadContent()
- {
- spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
- spriteFont = Content.Load<SpriteFont>("gameFont");
- shipModel = Content.Load<Model>("Ship");
- groundModel = Content.Load<Model>("Ground");
- }
- #endregion
- #region Update and Draw
- /// <summary>
- /// Allows the game to run logic.
- /// </summary>
- protected override void Update(GameTime gameTime)
- {
- lastKeyboardState = currentKeyboardState;
- lastGamePadState = currentGamePadState;
- lastMousState = currentMouseState;
- #if WINDOWS_PHONE
- currentKeyboardState = new KeyboardState();
- #else
- currentKeyboardState = Keyboard.GetState();
- #endif
- currentGamePadState = GamePad.GetState(PlayerIndex.One);
- currentMouseState = Mouse.GetState();
- // Exit when the Escape key or Back button is pressed
- if (currentKeyboardState.IsKeyDown(Keys.Escape) ||
- currentGamePadState.Buttons.Back == ButtonState.Pressed)
- {
- Exit();
- }
- bool touchTopLeft = currentMouseState.LeftButton == ButtonState.Pressed &&
- lastMousState.LeftButton != ButtonState.Pressed &&
- currentMouseState.X < GraphicsDevice.Viewport.Width / 10 &&
- currentMouseState.Y < GraphicsDevice.Viewport.Height / 10;
- // Pressing the A button or key toggles the spring behavior on and off
- if (lastKeyboardState.IsKeyUp(Keys.A) &&
- (currentKeyboardState.IsKeyDown(Keys.A)) ||
- (lastGamePadState.Buttons.A == ButtonState.Released &&
- currentGamePadState.Buttons.A == ButtonState.Pressed) ||
- touchTopLeft)
- {
- cameraSpringEnabled = !cameraSpringEnabled;
- }
- // Reset the ship on R key or right thumb stick clicked
- if (currentKeyboardState.IsKeyDown(Keys.R) ||
- currentGamePadState.Buttons.RightStick == ButtonState.Pressed)
- {
- ship.Reset();
- camera.Reset();
- }
- // Update the ship
- ship.Update(gameTime);
- // Update the camera to chase the new target
- UpdateCameraChaseTarget();
- // The chase camera's update behavior is the springs, but we can
- // use the Reset method to have a locked, spring-less camera
- if (cameraSpringEnabled)
- camera.Update(gameTime);
- else
- camera.Reset();
- base.Update(gameTime);
- }
- /// <summary>
- /// Update the values to be chased by the camera
- /// </summary>
- private void UpdateCameraChaseTarget()
- {
- camera.ChasePosition = ship.Position;
- camera.ChaseDirection = ship.Direction;
- camera.Up = ship.Up;
- }
- /// <summary>
- /// Draws the ship and ground.
- /// </summary>
- protected override void Draw(GameTime gameTime)
- {
- GraphicsDevice device = graphics.GraphicsDevice;
- device.Clear(Color.CornflowerBlue);
- GraphicsDevice.BlendState = BlendState.Opaque;
- GraphicsDevice.DepthStencilState = DepthStencilState.Default;
- GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
- DrawModel(shipModel, ship.World);
- DrawModel(groundModel, Matrix.Identity);
- DrawOverlayText();
- base.Draw(gameTime);
- }
- /// <summary>
- /// Simple model drawing method. The interesting part here is that
- /// the view and projection matrices are taken from the camera object.
- /// </summary>
- private void DrawModel(Model model, Matrix world)
- {
- Matrix[] transforms = new Matrix[model.Bones.Count];
- model.CopyAbsoluteBoneTransformsTo(transforms);
- foreach (ModelMesh mesh in model.Meshes)
- {
- foreach (BasicEffect effect in mesh.Effects)
- {
- effect.EnableDefaultLighting();
- effect.World = transforms[mesh.ParentBone.Index] * world;
- // Use the matrices provided by the chase camera
- effect.View = camera.View;
- effect.Projection = camera.Projection;
- }
- mesh.Draw();
- }
- }
- /// <summary>
- /// Displays an overlay showing what the controls are,
- /// and which settings are currently selected.
- /// </summary>
- private void DrawOverlayText()
- {
- spriteBatch.Begin();
- string text = "-Touch, Right Trigger, or Spacebar = thrust\n" +
- "-Screen edges, Left Thumb Stick,\n or Arrow keys = steer\n" +
- "-Press A or touch the top left corner\n to toggle camera spring (" + (cameraSpringEnabled ?
- "on" : "off") + ")";
- // Draw the string twice to create a drop shadow, first colored black
- // and offset one pixel to the bottom right, then again in white at the
- // intended position. This makes text easier to read over the background.
- spriteBatch.DrawString(spriteFont, text, new Vector2(65, 65), Color.Black);
- spriteBatch.DrawString(spriteFont, text, new Vector2(64, 64), Color.White);
- spriteBatch.End();
- }
- #endregion
- }
- #region Entry Point
- /// <summary>
- /// The main entry point for the application.
- /// </summary>
- static class Program
- {
- static void Main()
- {
- using (ChaseCameraGame game = new ChaseCameraGame())
- {
- game.Run();
- }
- }
- }
- #endregion
- }
|