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();
}
}
}
}