我正在制作 XNA 游戏,我希望在按住鼠标按钮时光标停止。现在通过将光标位置设置为每 1/60 秒到某个位置会使光标看起来滞后,有时如果光标移动得足够快以到达屏幕边框,从那一刻到下一个位置重置,增量位置是没有正确计算。此外,从屏幕边缘开始向同一边缘移动不会得到任何正确的增量。
如何获得正确的光标增量并且不会因光标停在屏幕边缘而感到沮丧?
如果您将鼠标锁定到的位置太靠近边缘,那么您就不走运了。
我建议你在拖动动作开始时隐藏光标,保存位置并偷偷将光标移动到屏幕中央。拖动结束时,只需将光标恢复到之前的位置。
很容易,假设我明白你的意思。
为了根据鼠标移动第一人称相机,我们需要计算每帧的增量,然后将鼠标移回屏幕中心。
为此,我们将存储屏幕中心的位置。我们还需要一个 MouseState 变量和一个 yaw 和一个 pitch 浮动来存储我们当前的相机旋转。我也喜欢根据游戏的分辨率设置旋转速度:
MouseState currentMouseState;
Vector2 screenCenter;
float YrotationSpeed;
float XrotatiobSpeed;
float yaw = 0;
float pitch = 0;
...
protected override void LoadContent()
{
YrotationSpeed = (float)graphics.PreferredBackBufferWidth / 10000.0f;
XrotatiobSpeed = (float)graphics.PreferredBackBufferHeight / 12000.0f;
screenCenter = new Vector2(graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height) / 2;
}
现在,要计算鼠标在最后一帧中移动了多少,我们将使用这个函数:
private void HandleMouse(GameTime gameTime)
{
currentMouseState = Mouse.GetState();
float amount = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f;
if (currentMouseState.X != screenCenter.X)
{
yaw -= YrotationSpeed * (currentMouseState.X - screenCenter.X) * amount;
}
if (currentMouseState.Y != screenCenter.Y)
{
pitch -= XrotatiobSpeed * (currentMouseState.Y - screenCenter.Y) * amount;
if (pitch > MathHelper.ToRadians(90))
pitch = MathHelper.ToRadians(90);
if (pitch < MathHelper.ToRadians(-50)) //Preventing the user from looking all the way down (and seeing the character doesn't have any legs..)
pitch = MathHelper.ToRadians(-50);
}
Mouse.SetPosition((int)screenCenter.X, (int)screenCenter.Y);
}
最后:
要更新相机和视图矩阵,您可以使用以下函数,该函数应在我们更新了偏航角和俯仰角后执行:
public void UpdateCamera(float yaw, float pitch, Vector3 position)
{
Matrix cameraRotation = Matrix.CreateRotationX(pitch) * Matrix.CreateRotationY(yaw);
Vector3 cameraOriginalTarget = new Vector3(0, 0, -1);
Vector3 cameraRotatedTarget = Vector3.Transform(cameraOriginalTarget, cameraRotation);
Vector3 cameraFinalTarget = position + cameraRotatedTarget;
Vector3 cameraOriginalUpVector = new Vector3(0, 1, 0);
Vector3 cameraRotatedUpVector = Vector3.Transform(cameraOriginalUpVector, cameraRotation);
view = Matrix.CreateLookAt(position, cameraFinalTarget, cameraRotatedUpVector);
}
编辑:好吧,当我重新阅读这个问题时,我意识到我的答案并不完全符合您的要求。尽管如此,它确实展示了如何在不到达屏幕边界的情况下计算鼠标增量。
为了匹配我对您问题的回答,您所需要的只是微小的调整。
顺便说一句,除非您愿意在屏幕中间绘制鼠标图像,否则任何方法都会显得有些迟钝。因此,我强烈建议您隐藏光标。为此,只需添加以下行:
this.IsMouseVisible = false;