我有 3 个类:游戏类、相机类和模型类。项目构建并运行,模型出现,当我按下 w 并使其前进时,相机会跟随它,但是当我重新启动项目并旋转模型以面对任何其他方式时,它似乎在俯冲,而不是去是的,我试图实现的是遵循模型的相机,
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 test1
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
//Visual components
Ship ship = new Ship();
Camera _camera;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
// this.graphics.ToggleFullScreen();
this._camera = new Camera(graphics.GraphicsDevice.Viewport);
this._camera.LookAt = new Vector3(0.0f, 0.0f, 0.0f);
this._camera.Position = new Vector3(0.0f, -5000.0f, 1000.0f);
base.Initialize();
}
protected override void LoadContent()
{
ship.Model = Content.Load<Model>("Models/p1_wedge");
ship.Transforms = _camera.SetupEffectDefaults(ship.Model);
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();
// Get some input.
UpdateInput();
base.Update(gameTime);
}
protected void UpdateInput()
{
// Get the game pad state.
GamePadState currentState = GamePad.GetState(PlayerIndex.One);
KeyboardState currentKeyState = Keyboard.GetState();
ship.Update(currentState);
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
//camera
this._camera.Update();
_camera.LookAt = ship.Position;
Matrix shipTransformMatrix = ship.RotationMatrix
* Matrix.CreateTranslation(ship.Position);
DrawModel(ship.Model, shipTransformMatrix, ship.Transforms);
base.Draw(gameTime);
}
public void DrawModel(Model model, Matrix modelTransform,
Matrix[] absoluteBoneTransforms)
{
//Draw the model, a model can have multiple meshes, so loop
foreach (ModelMesh mesh in model.Meshes)
{
//This is where the mesh orientation is set
foreach (BasicEffect effect in mesh.Effects)
{
effect.World =
absoluteBoneTransforms[mesh.ParentBone.Index] *
modelTransform;
effect.Projection = _camera.ProjectionMatrix;
effect.View = _camera.ViewMatrix;
}
//Draw the mesh, will use the effects set above.
mesh.Draw();
}
}
}
}
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 test1
{
public class Camera
{
private Vector3 _position;
private Vector3 _lookAt;
private Matrix _viewMatrix;
private Matrix _projectionMatrix;
private float _aspectRatio;
public Camera(Viewport viewport)
{
this._aspectRatio = ((float)viewport.Width) / ((float)viewport.Height);
this._projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(40.0f),
this._aspectRatio,
1.0f,
10000.0f);
}
public Matrix[] SetupEffectDefaults(Model myModel)
{
Matrix[] absoluteTransforms = new Matrix[myModel.Bones.Count];
myModel.CopyAbsoluteBoneTransformsTo(absoluteTransforms);
foreach (ModelMesh mesh in myModel.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.Projection = ProjectionMatrix;
effect.View = ViewMatrix;
}
}
return absoluteTransforms;
}
public Vector3 Position
{
get { return this._position; }
set { this._position = value; }
}
public Vector3 LookAt //= Vector3.Zero;
{
get { return this._lookAt; }
set { this._lookAt = value; }
}
public Matrix ViewMatrix
{
get { return this._viewMatrix; }
}
public Matrix ProjectionMatrix
{
get { return this._projectionMatrix; }
}
public void Update()
{
this._viewMatrix =
Matrix.CreateLookAt(this._position, this._lookAt, Vector3.Up);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace test1
{
class Ship
{
public Model Model;
public Matrix[] Transforms;
//Position of the model in world space
public Vector3 Position = Vector3.Zero;
//Velocity of the model, applied each frame to the model's position
public Vector3 Velocity = Vector3.Zero;
private const float VelocityScale = 5.0f;
public Matrix RotationMatrix =
Matrix.CreateRotationX(MathHelper.PiOver2);
private float rotation;
public float Rotation
{
get { return rotation; }
set
{
float newVal = value;
while (newVal >= MathHelper.TwoPi)
{
newVal -= MathHelper.TwoPi;
}
while (newVal < 0)
{
newVal += MathHelper.TwoPi;
}
if (rotation != value)
{
rotation = value;
RotationMatrix =
Matrix.CreateRotationX(MathHelper.PiOver2) *
Matrix.CreateRotationZ(rotation);
}
}
}
public void Update(GamePadState controllerState)
{
KeyboardState currentKeyState = Keyboard.GetState();
if (currentKeyState.IsKeyDown(Keys.A))
Rotation += 0.10f;
else
// Rotate the model using the left thumbstick, and scale it down.
Rotation -= controllerState.ThumbSticks.Left.X * 0.10f;
if (currentKeyState.IsKeyDown(Keys.D))
Rotation -= 0.10f;
if (currentKeyState.IsKeyDown(Keys.W))
Velocity += RotationMatrix.Forward * VelocityScale;
else
// Finally, add this vector to our velocity.
Velocity += RotationMatrix.Forward * VelocityScale *
controllerState.Triggers.Right;
// In case you get lost, press A to warp back to the center.
if (currentKeyState.IsKeyDown(Keys.Enter))
{
Position = Vector3.Zero;
Velocity = Vector3.Zero;
Rotation = 0.0f;
}
Position += Velocity;
Velocity *= 0.95f;
}
}
}