Slides built from Carter Chapter 5
Some overhead Copy 3d demo project from last week and rename project folder to InputDemo Open and rename the project in AssemblyInfo.cs and change game id You can just create a new project I’ve done both
Creating a library File -> new project Windows Game Library (3.0) Name it XELibrary, also the solution
Adding FPS.cs Copy file FPS.cs into solution directory Select Project -> Show all files Right click on file name Select add to project See the FPS lab from the labs. Edit file and change namespace to XELibrary Let’s also remove the Class1.cs Right click -> delete
Input Handler Project->add component Open InputHandler.cs
InputHandler Game Service using Microsoft.Xna.Framework.Input; Might need this. public interface IInputHandler { }; Partial class can be defined over multiple definitions (ie more than one source file) public partial class InputHandler : Microsoft.Xna.Framework.GameComponent, Inherit from IInputHandler above IInputHandler Since a service, must add it as a service game.Services.AddService(typeof(IInputHandler), this);
Add a camera component Project -> add new item
Camera game component Add a variable for our input handler and graphics Protected so can be accessed by protected IInputHandler input; base class private GraphicsDeviceManager graphics; Initialize in camera constructor graphics = (GraphicsDeviceManager)Game.Services.GetSe rvice(typeof(IGraphicsDeviceManager)); input = (IInputHandler)game.Services.GetService(ty peof(IInputHandler));
Copy camera code from last time Initialize() Base.Initialize(); InitializeCamera(); // from last time next slide Initialize base first so we have access to the graphics device here which is initialized there. Add the declarations as well private Matrix projection; private Matrix view; protected Vector3 cameraPosition = new Vector3(0.0f, 0.0f, 3.0f); private Vector3 cameraTarget = Vector3.Zero; private Vector3 cameraUpVector = Vector3.Up;
InitializeCamera() private void InitializeCamera() We saw this last time. { float aspectRatio = (float)graphics.GraphicsDevice.Viewport.Width / (float)graphics.GraphicsDevice.Viewport.Height; Matrix.CreatePerspectiveFieldOfView( MathHelper.PiOver4,aspectRatio,0.001f,1000.0f, out projection); Matrix.CreateLookAt(ref cameraPosition, ref cameraTarget, ref cameraUpVector, out view); }
Access method for matrices public Matrix View { get { return view; } } public Matrix Projection { get {reutnr projection; }} Now we can access the view and projection matrix from the camera in a game that uses this library.
Now create a demo Can start a new project, or copy the one from last time Add all of the code from the previous example is starting anew Now remove the Matrix view, projection; decls Remove the Initialize camera and all access to the camera Project -> add reference -> browse and add a reference to XELibrary.dll
Add some code in game.cs using XELibrary; Declarations Camera camera; Initialize() camera = new Camera(this) Change Draw() effect.Projection = camera.Projection; effect.View = camera.View;
Adding keyboard to InputHandler Declare private KeyboardState keyboardState; Update keyboardState = Keyboard.GetState(); if (keyboardState.IsKeyDown(Keys.Escape)) Game.Exit(); OK so now all we can do is exit on an escape! But this is part of our camera, so including this camera will include this code!
Now for some camera control Declare private Vector3 cameraReference = new Vector3(0.0f, 0.0f, -1.0f); private float cameraYaw = 0.0f; Update() Matrix rotationMatrix; Matrix.CreateRotationY(MathHelper.ToRadians(cameraYaw), out rotationMatrix); Vector3 transformedReference; Vector3.Transform(ref cameraReference, ref rotationMatrix, out transformedReference); // Calculate the position the camera is looking at. Vector3.Add(ref cameraPosition, ref transformedReference, out cameraTarget); Matrix.CreateLookAt(ref cameraPosition, ref cameraTarget, ref cameraUpVector, out view);
In IInputHandler public interface IInputHandler { KeyboardState KeyboardState { get; } GamePadState[] GamePads { get; } #if !XBOX360 MouseState MouseState { get; } MouseState PreviousMouseState { get; } #endif }
Add access in InputHandler public KeyboardState KeyboardState { get { return(keyboardState); } } public GamePadState[] GamePads {get { return(gamePads); } } #if !XBOX360 public MouseState MouseState { get { return(mouseState); }} public MouseState PreviousMouseState {get { return(prevMouseState); } } #endif
Use exposed members in camera Update() if (input.KeyboardState.IsKeyDown(Keys.Left)) cameraYaw += spinRate; if (input.KeyboardState.IsKeyDown(Keys.Right)) cameraYaw -= spinRate; //reset camera angle if needed if (cameraYaw > 360) cameraYaw -= 360; else if (cameraYaw < 0) cameraYaw += 360;
Back to Game Decl private InputHandler input Constructor input = new InputHandler(this); Components.Add(input); We execute and get the objects flying by with our updates as fast as possible.
New constructor for FPS public FPS(Game game, bool synchWithVerticalRetrace, bool isFixedTimeStep) : this(game, synchWithVerticalRetrace, isFixedTimeStep, game.TargetElapsedTime) {} #if DEBUG Instead of as fast as fps = new FPS(this); possible, we can do #else 60Hz fps = new FPS(this, true, false); #endif
GamePad GamePadState[] GamePads { get; } // Iinput Handler Class InputHandler decls private GamePadState[] gamePads = new GamePadState[4]; public GamePadState[] GamePads {get { return(gamePads); } } InputHandler Update() gamePads[0] = GamePad.GetState(PlayerIndex.One); gamePads[1] = GamePad.GetState(PlayerIndex.Two); gamePads[2] = GamePad.GetState(PlayerIndex.Three); gamePads[3] = GamePad.GetState(PlayerIndex.Four); if (gamePads[0].Buttons.Back == ButtonState.Pressed) Game.Exit();
GamePad: camera class float timeDelta = (float)gameTime.ElapsedGameTime.TotalSeconds; if (input.KeyboardState.IsKeyDown(Keys.Left) || (input.GamePads[playerIndex].ThumbSticks.Right.X < 0)) cameraYaw += (spinRate * timeDelta); if (input.KeyboardState.IsKeyDown(Keys.Right) || (input.GamePads[playerIndex].ThumbSticks.Right.X > 0)) cameraYaw -= (spinRate * timeDelta);
GamePad: DPad Suppose we wanted to use the Dpad to also rotate if (input.KeyboardState.IsKeyDown(Keys.Left) || (input.GamePads[playerIndex].ThumbSticks.Right.X < 0) || (gamePadState.Dpad.Left == ButtonState.Pressed)) cameraYaw += (spinRate * timeDelta); Dpad behaves like a button
GamePad Triggers Return a value between 0 =pressed and 1 =fully pressed. Vibration 2 motors, left is low-frequency, right is high-frequency if (input.GamePads[0].IsConnected) GamePad.SetVibration(PlayerIndex.One, input.GamePads[0].Triggers.Left, input.GamePads[0].Triggers.Right); Change title to hold these values This.Window.Title = “left: “ + input.GamePads[0].Triggers.Left.ToString () + “; right: “ + input.GamePads[0].Triggers.Right.ToString();
Mouse Declare #if !XBOX360 private MouseState mouseState; private MouseState prevMouseState; #endif Constructor #if !XBOX360 Game.IsMouseVisible = true; prevMouseState = Mouse.GetState(); #endif
Mouse Update #if !XBOX360 prevMouseState = mouseState; //Set our previous state mouseState = Mouse.GetState(); //Get our new state #endif Properties #if !XBOX360 public MouseState MouseState {get { return(mouseState); }} public MouseState PreviousMouseState {get { return(prevMouseState); }} #endif
Mouse: controlling camera #if !XBOX360 if ((input.PreviousMouseState.X > input.MouseState.X) && (input.MouseState.LeftButton == ButtonState.Pressed)) cameraYaw += (spinRate * timeDelta); else if ((input.PreviousMouseState.X < input.MouseState.X) && (input.MouseState.LeftButton == ButtonState.Pressed)) cameraYaw -= (spinRate * timeDelta); #endif
Improving demo Add some more quads with world = SomeTransform(s) DrawRectangle(world); Also remove culling for now just in case graphics.GraphicsDevice.RenderState.CullMode = CullMode.None;
Camera Pitch Just like yaw except use up and down arrow or right thumbstick if ((input.PreviousMouseState.Y > input.MouseState.Y) && (input.MouseState.LeftButton == ButtonState.Pressed)) cameraPitch += (spinRate * timeDelta); else if ((input.PreviousMouseState.Y < input.MouseState.Y) && (input.MouseState.LeftButton == ButtonState.Pressed)) cameraPitch -= (spinRate * timeDelta); Also set camera pitch to go between -90 and 90 if (cameraPitch > 89) cameraPitch = 89; if (cameraPitch < -89) cameraPitch = -89;
FirstPersonCamera: Movement public partial class FirstPersonCamera : Camera { public FirstPersonCamera(Game game) : base(game) { // TODO: Construct any child components here } Derive from stationary Camera
FirstPersonCamera: Movement public override void Update(GameTime gameTime) { movement = Vector3.Zero; //reset movement vector if (input.KeyboardState.IsKeyDown(Keys.A) || (input.GamePads[playerIndex].ThumbSticks.Left.X < 0)) movement.X--; if (input.KeyboardState.IsKeyDown(Keys.D) || (input.GamePads[playerIndex].ThumbSticks.Left.X > 0)) movement.X++;
Recommend
More recommend