C#/ XNA获取硬件鼠标位置


10

我正在使用C#并尝试获取硬件鼠标的位置。我尝试的第一件事是简单的XNA功能,该功能易于使用

Vector2 position = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);

之后,我也绘制了鼠标,并且与Windows硬件鼠标相比,带有xna提供的坐标的新鼠标“松弛了”。我的意思是,它落后了几帧。例如,如果游戏以600 fps的速度运行,则诅咒会响应,但是以60 fps的软件鼠标延迟不再可接受。因此,我尝试使用我认为是硬件鼠标的工具,

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetCursorPos(out POINT lpPoint);

但结果完全一样。我还尝试获取Windows窗体光标,这同样是一个死胡同-可行,但有同样的延迟。杂乱无章的xna功能:

GraphicsDeviceManager.SynchronizeWithVerticalRetrace = true/false
Game.IsFixedTimeStep = true/fale

确实有一些明显的原因改变了延迟时间,但是最重要的是,无论它是否仍在默认的Windows鼠标后面。我在某些游戏中看到过,它们提供了硬件加速鼠标的选项,而在其他游戏中(我认为)默认情况下已经存在。任何人都可以就如何实现这一目标提供一些指导。


2
我不认为Mouse.GetState()坏了。确定要在绘制鼠标的同一帧中找到鼠标位置吗?还记得在Windows光标具有加速/减速启用,所以感觉更加敏感。如果您想更接近硬件,则应点击DirectInput,它将为您提供移动增量而不是绝对的鼠标位置。但是我相信Mouse.GetState()在XNA中仍然是正确的方法。
熊猫睡衣

不,Mouse.GetState()它不坏,只要IsFixedTimeStep == true人们不应该看到延迟,除非直接与可见的Windows鼠标比较。但是,在较低帧率下将IsFixedTimeStep设置为false则每个人都可以看到。关于直接输入,我认为是posposability(不得已)。
Sunder

不知道这是否是您想要的,但是如何更改光标精灵在窗口中时的显示状态,然后使其始终可见?
William Mariager 2012年

那就是我正在做的事情,问题是我不想只显示它,而是想知道鼠标的确切位置。但是我得到的却比它应该的要落后一点。
Sunder

Answers:


17

您看到的不是输入滞后。

要获取Windows中光标的位置,可以使用WM_MOUSEMOVEGetCursorPos。它们都在Windows处理完光标后提供了光标的位置,并应用了诸如加速之类的功能。这是Windows使用的光标位置,包括用于绘制的位置。而且几乎总是您想要使用的东西。

这就是XNA所使用的。具体来说GetCursorPosMSDN)。这意味着,当您调用时Mouse.GetState,您将获得Windows所看到的光标的真实位置-几乎为零延迟。

现在,您可以使用WM_INPUT(或DirectInput,尽管已弃用)。这为您提供了原始指针数据。这是Windows之前无法应用加速之类的东西,通常不是您想要的。

您看到的输出滞后。

这是因为“ 硬件光标 ”。这是得到由GPU在绘制在屏幕上的小精灵其管道的末端。我的意思是结局。它位于帧缓冲区之后-随着图像被发送到监视器,它被插入到数据流中。它之所以反应迅速,是因为其位置是通过直接设置GPU寄存器来设置的。管道中根本没有等待。

另一方面,您的游戏必须通过GPU管道。这就增加了很多延迟。其中对您来说最有问题的是双缓冲-(我很确定)您不能在XNA 4中关闭它。您不会直接绘制到帧缓冲区-绘制到了后缓冲区。大约每16毫秒(60FPS)显示一次。这意味着您在接收到Mouse.GetState根据屏幕上的结果得到某物的结果之间的间隔至少为16ms 。可能更长。当然比硬件游标慢很多。

那么有什么解决方案呢?

一种是使用SetCursorMSDN)将硬件光标显示的图像更改为更适合您的游戏的图像(或仅与Windows光标一起使用)。

另一个(容易得多)是仅接受滞后,并设置Game.IsMouseVisible = false为隐藏相对滞后。在游戏中显示您自己的光标。这将比隐藏的Windows光标慢16毫秒-但是谁在乎呢?玩家已经习惯了。无论如何,16ms几乎在视觉上是无法察觉的(这就是为什么我们以60FPS渲染事物的原因)。


感谢您对此事的详细解释。我很可能只会坚持使用XNA鼠标。在接受之前要稍等一下,以防有人有其他解决方法。
Sunder

我猜是否接受延迟是一个应该通过游戏测试来回答的问题。
Zonko
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.