using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; namespace MouseClickMovement { /// /// This is the main type for your game /// public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; //Used this for some debugging SpriteFont debugFont; //string debugText; //Reserve memory for the mouse states MouseState newMouseState, oldMouseState; //Reserve memory for the models Model myModel; Model Ground; // Reserve memory to move and rotate the model float myModelRotation; Vector3 myModelPosition; //used to calculate the amount of rotation of the camera float totalCamPitch = 0f; float totalCamYaw = 0f; //the final camera position Vector3 finalCameraPosition; // the camera rotation matrix Matrix cameraRotation; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; //Gets rid of the jaggy edges of your model graphics.PreferMultiSampling = true; //set mouse vissible IsMouseVisible = true; } /// /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// protected override void Initialize() { // TODO: Add your initialization logic here base.Initialize(); } /// /// LoadContent will be called once per game and is the place to load /// all of your content. /// protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); // TODO: use this.Content to load your game content here debugFont = Content.Load("debugFont"); //Loads models, import your own and point to the right file locations myModel = Content.Load("frigate"); Ground = Content.Load("groundplane"); //Sets my model's position myModelPosition = Vector3.Zero; //Rotates my model to the right angle myModelRotation = MathHelper.ToRadians(-90f); // Sets initial camera pitch totalCamPitch = -35; } /// /// UnloadContent will be called once per game and is the place to unload /// all content. /// protected override void UnloadContent() { // TODO: Unload any non ContentManager content here } /// /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// /// Provides a snapshot of timing values. protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); oldMouseState = newMouseState; newMouseState = Mouse.GetState(); // CAMERA ORBIT CODE // sets the camera a little to the back of the model, since my model is small i use a small number in Z Vector3 cameraOffset = new Vector3(0, 0, 50); //if mouse button is pressed if (newMouseState.LeftButton == ButtonState.Pressed) { //set mouse invissible (not really needed) IsMouseVisible = false; //Simply set the total camera pitch and yaw to the difference in mouseposition, use -= to invert totalCamPitch += (oldMouseState.Y - newMouseState.Y); totalCamYaw += (oldMouseState.X - newMouseState.X); //Set maximum pith to 89 degree's, read Google gimbal lock if you want to know why. if (totalCamPitch >= 89) { totalCamPitch = 89; } if (totalCamPitch <= -89) { totalCamPitch = -89; } } else { // put mouse back on if mouse button is released. IsMouseVisible = true; } //sets the camera rotation x and y equal to the total yaw and pitch cameraRotation = Matrix.CreateRotationX(MathHelper.ToRadians(totalCamPitch)) * Matrix.CreateRotationY(MathHelper.ToRadians(totalCamYaw)); // sets the camera position. Vector3 cameraRotatedPosition = Vector3.Transform(cameraOffset, cameraRotation); // finally sets the camera position behind the player finalCameraPosition = cameraRotatedPosition + myModelPosition; //debugText = "TotalCamPitch" + totalCamPitch; base.Update(gameTime); } /// /// This is called when the game should draw itself. /// /// Provides a snapshot of timing values. protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here Matrix[] transforms = new Matrix[myModel.Bones.Count]; myModel.CopyAbsoluteBoneTransformsTo(transforms); //draw the mymodel with the camera attached to it. foreach (ModelMesh mesh in myModel.Meshes) { foreach (BasicEffect effect in mesh.Effects) { effect.EnableDefaultLighting(); effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateRotationY(myModelRotation) * Matrix.CreateTranslation(myModelPosition); effect.View = Matrix.CreateLookAt(finalCameraPosition, myModelPosition, Vector3.Up); effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45f), graphics.GraphicsDevice.Viewport.AspectRatio, 1, 10000); } mesh.Draw(); } //draws the ground and anything else with the rotation and position given. ModelDraw(Ground, 0f, new Vector3(0, -100, 0)); base.Draw(gameTime); } /// /// Draws a model on the screen /// /// The model /// Sets the rotation of the model in the world /// Sets the position of the model in the world private void ModelDraw(Model model,float rotation, Vector3 position) { 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] * Matrix.CreateScale(1f) * Matrix.CreateRotationY(rotation) * Matrix.CreateTranslation(position); effect.View = Matrix.CreateLookAt(finalCameraPosition, myModelPosition, Vector3.Up); effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45f), graphics.GraphicsDevice.Viewport.AspectRatio, 1, 10000); } mesh.Draw(); } } } }