所以,我正在XNA制作第三人称游戏。我已经创建了一个可以在限制范围内进行俯仰的摄像机,并且应该可以使整个360度偏航。
课程如下所示:
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 Assignment_3_Redesign
{
/// <summary>
/// This is a game component that implements IUpdateable.
/// </summary>
public class Camera : Microsoft.Xna.Framework.GameComponent
{
//Constrain where our camera can wander in the X and Z plane
public Rectangle XZBoundingBox;
//Angular bounds for camera.
float minPitchIncr = -12;
float maxPitchIncr = 38;
float currentPitchIncr = 12;
float currentYawAngle = 0;
//Matrices to pass to effects.
public Matrix view { get; protected set; }
public Matrix projection { get; protected set; }
//Important directional vars.
public Vector3 pos;
public Vector3 look;
private Vector3 up;
//Mouse Input
//X -- yaw; Y-- pitch
private MouseState prevMouseState;
private MouseState tempMS;
private KeyboardState keyboardState;
//Speed to move camera at for translates.
float Speed = 3;
public Camera(Game game, Vector3 pos, Vector3 target, Vector3 up, Rectangle bounding)
: base(game)
{
this.pos = pos;
this.look = (target - pos);
this.look.Normalize();
this.up = up;
this.view = Matrix.CreateLookAt(pos, target, up);
XZBoundingBox = bounding;
this.projection = Matrix.CreatePerspectiveFieldOfView
(MathHelper.PiOver4,
(float)Game.Window.ClientBounds.Width /
(float)Game.Window.ClientBounds.Height,
1, 500);
}
private void CreateLookAt()
{ view = Matrix.CreateLookAt(pos, pos + look, up); }
//Returns current camera direction as vector.
public Vector3 GetCameraDirection
{ get { return look; } }
///
public override void Initialize()
{
// TODO: Add your initialization code here
Mouse.SetPosition(Game.Window.ClientBounds.Width / 2,
Game.Window.ClientBounds.Height / 2);
prevMouseState = Mouse.GetState();
base.Initialize();
}
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public override void Update(GameTime gameTime)
{
Vector3 tempPos= new Vector3(0.0f,0.0f,0.0f);
//Get keyboard commands
keyboardState = Keyboard.GetState();
/*
//Select object
if (keyboard.IsKeyDown(Keys.D1))
objSelected = 0;
if (keyboard.IsKeyDown(Keys.D2))
objSelected = 1;*/
//Translation
if (keyboardState.IsKeyDown(Keys.A)) //strafe +X (rel)
{
tempPos -= Vector3.Cross(up, look) * Speed;
tempPos.Y = 0.0f;
if (XZBoundingBox.Contains((int)(pos - Vector3.Normalize(tempPos) * Speed).X,
(int)(pos - Vector3.Normalize(tempPos) * Speed).Z))
pos -= Vector3.Normalize(tempPos) * Speed;
}
if (keyboardState.IsKeyDown(Keys.D)) //strafe -X (rel)
{
tempPos -= Vector3.Cross(up, look) * Speed;
tempPos.Y = 0.0f;
if (XZBoundingBox.Contains((int)(pos - Vector3.Normalize(tempPos) * Speed).X,
(int)(pos - Vector3.Normalize(tempPos) * Speed).Z))
pos += Vector3.Normalize(tempPos) * Speed;
}
if (keyboardState.IsKeyDown(Keys.W)) //+Z (rel)
{
tempPos += look * Speed;
tempPos.Y = 0.0f;
if (XZBoundingBox.Contains((int)(pos - Vector3.Normalize(tempPos) * Speed).X,
(int)(pos - Vector3.Normalize(tempPos) * Speed).Z))
pos += Vector3.Normalize(tempPos) * Speed;
}
if (keyboardState.IsKeyDown(Keys.S)) //-Z (rel)
{
tempPos -= look;
tempPos.Y = 0.0f;
if (XZBoundingBox.Contains((int)(pos - Vector3.Normalize(tempPos) * Speed).X,
(int)(pos - Vector3.Normalize(tempPos) * Speed).Z))
pos -= Vector3.Normalize(tempPos) * Speed;
}
//Get mouse commands to control camera direction;
//Yaw rot.
tempMS = Mouse.GetState();
if (tempMS != prevMouseState)
{
currentYawAngle += (tempMS.X - prevMouseState.X) * (-MathHelper.PiOver4 / 150);
currentYawAngle = MathHelper.WrapAngle(currentYawAngle);
if (currentPitchIncr + (tempMS.Y - prevMouseState.Y) < maxPitchIncr &&
currentPitchIncr + (tempMS.Y - prevMouseState.Y) > minPitchIncr)
currentPitchIncr += tempMS.Y - prevMouseState.Y;
if (currentPitchIncr > maxPitchIncr) currentPitchIncr = maxPitchIncr;
else if (currentPitchIncr < minPitchIncr) currentPitchIncr = minPitchIncr;
look = Vector3.Transform(Vector3.Forward,
Matrix.CreateFromYawPitchRoll(currentYawAngle,
currentPitchIncr * (-MathHelper.PiOver4 / 150), 0.0f));
}
//reset prevMouseState
prevMouseState = Mouse.GetState();
base.Update(gameTime);
CreateLookAt();
}
}
}
现在这就是我想做的......差不多。问题在于,当我旋转时,它不会在偏航中越过Pi / -Pi。换句话说,你不能完全360度旋转。
我在某些条件下犯了错误吗? (我不会怀疑它......我已经盯着它看了太长时间,玩弄它并破坏它。)
这是一个示例声明:
camera = new Camera(this, new Vector3(0, 20, 40), Vector3.Zero, Vector3.Up,
new Rectangle(-800,-800,1600,1600));
还有关于相机类整体的任何想法吗?
感谢您的帮助!
编辑1
这在技术上适用于#classproject。为了清楚起见,我想提一下。作业是开放式的,我正在努力投入更多时间,因为我想制作一个可靠的框架来制作WinPhone游戏......
答案 0 :(得分:4)
您可以随时将鼠标光标“重置”回屏幕中间。这样你就可以拥有无限的动作
使用此技术时,请确保隐藏原始鼠标指针,因为它看起来非常糟糕。如果你仍然需要一个鼠标指针可见,只需在你自己跟踪的鼠标坐标上blit你自己的鼠标指针。