我正在使用 XNA 4.0 和 c# 制作游戏。我刚刚完成了我的相机课,它几乎按预期工作,除了一件事。我可以用鼠标移动来旋转相机,但问题是当我到达屏幕边缘时,鼠标停止,相机移动也停止。
有什么方法可以让鼠标指针在屏幕边界之外,以便能够继续跟踪指针?或者有没有更简单的方法?
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;
public class ArcBallCamera
{
private float speeder = 100;
public ArcBallCamera(float aspectRation, Vector3 lookAt)
: this(aspectRation, MathHelper.PiOver4, lookAt, Vector3.Up, 0.1f, float.MaxValue) { }
public ArcBallCamera(float aspectRatio, float fieldOfView, Vector3 lookAt, Vector3 up, float nearPlane, float farPlane)
{
this.aspectRatio = aspectRatio;
this.fieldOfView = fieldOfView;
this.lookAt = lookAt;
this.nearPlane = nearPlane;
this.farPlane = farPlane;
}
/// <summary>
/// Recreates our view matrix, then signals that the view matrix
/// is clean.
/// </summary>
public void ReCreateViewMatrix()
{
//Calculate the relative position of the camera
position = Vector3.Transform(Vector3.Backward, Matrix.CreateFromYawPitchRoll(yaw, pitch, 0));
//Convert the relative position to the absolute position
position *= zoom;
position += lookAt;
//Calculate a new viewmatrix
viewMatrix = Matrix.CreateLookAt(position, lookAt, Vector3.Up);
viewMatrixDirty = false;
}
/// <summary>
/// Recreates our projection matrix, then signals that the projection
/// matrix is clean.
/// </summary>
public void ReCreateProjectionMatrix()
{
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(fieldOfView, AspectRatio, nearPlane, farPlane);
projectionMatrixDirty = false;
}
#region HelperMethods
/// <summary>
/// Moves the camera and lookAt at to the right,
/// as seen from the camera, while keeping the same height
/// </summary>
public void MoveCameraRight(float amount)
{
Vector3 right = Vector3.Normalize(LookAt - Position); //calculate forward
right = Vector3.Cross(right, Vector3.Up); //calculate the real right
//right.Y = 0;
right.Normalize();
LookAt += right * amount;
}
/// <summary>
/// Moves the camera and lookAt forward,
/// as seen from the camera, while keeping the same height
/// </summary>
public void MoveCameraForward(float amount)
{
Vector3 forward = Vector3.Normalize(LookAt - Position);
// forward.Y = 0;
forward.Normalize();
LookAt += forward * amount;
}
/// <summary>
/// Moves the camera and lookAt up or down,
/// LOL
/// </summary>
public void MoveCameraUp(float amount)
{
Vector3 up = Vector3.Normalize(LookAt - position);
up = Vector3.Cross(up, Vector3.Left); //Calculate the REAL FUCKING UP/DOWN
up.X = 0;
up.Z = 0;
up.Normalize();
LookAt += up * amount;
}
#endregion
#region FieldsAndProperties
//We don't need an update method because the camera only needs updating
//when we change one of it's parameters.
//We keep track if one of our matrices is dirty
//and reacalculate that matrix when it is accesed.
private bool viewMatrixDirty = true;
private bool projectionMatrixDirty = true;
public float MinPitch = -MathHelper.PiOver2 + 0.3f;
public float MaxPitch = MathHelper.PiOver2 - 0.3f;
private float pitch;
public float Pitch
{
get { return pitch; }
set
{
viewMatrixDirty = true;
pitch = MathHelper.Clamp(value, MinPitch, MaxPitch);
}
}
private float yaw;
public float Yaw
{
get { return yaw; }
set
{
viewMatrixDirty = true;
yaw = value;
}
}
private float fieldOfView;
public float FieldOfView
{
get { return fieldOfView; }
set
{
projectionMatrixDirty = true;
fieldOfView = value;
}
}
private float aspectRatio;
public float AspectRatio
{
get { return aspectRatio; }
set
{
projectionMatrixDirty = true;
aspectRatio = value;
}
}
private float nearPlane;
public float NearPlane
{
get { return nearPlane; }
set
{
projectionMatrixDirty = true;
nearPlane = value;
}
}
private float farPlane;
public float FarPlane
{
get { return farPlane; }
set
{
projectionMatrixDirty = true;
farPlane = value;
}
}
public float MinZoom = 1;
public float MaxZoom = float.MaxValue;
private float zoom = 1;
public float Zoom
{
get { return zoom; }
set
{
viewMatrixDirty = true;
zoom = MathHelper.Clamp(value, MinZoom, MaxZoom);
}
}
private Vector3 position;
public Vector3 Position
{
get
{
if (viewMatrixDirty)
{
ReCreateViewMatrix();
}
return position;
}
}
private Vector3 lookAt;
public Vector3 LookAt
{
get { return lookAt; }
set
{
viewMatrixDirty = true;
lookAt = value;
}
}
#endregion
#region ICamera Members
public Matrix ViewProjectionMatrix
{
get { return ViewMatrix * ProjectionMatrix; }
}
private Matrix viewMatrix;
public Matrix ViewMatrix
{
get
{
if (viewMatrixDirty)
{
ReCreateViewMatrix();
}
return viewMatrix;
}
}
private Matrix projectionMatrix;
public Matrix ProjectionMatrix
{
get
{
if (projectionMatrixDirty)
{
ReCreateProjectionMatrix();
}
return projectionMatrix;
}
}
#endregion
}