如何摆脱C#中的字符重复延迟?

http://www.microsoft.com/windowsxp/using/accessibility/characterrepeatrate.mspx – Windows中有一个选项可用于设置重复延迟。 这意味着如果持续按下键,第一次击键和其他击键之间的延迟。 我正在创造一种游戏,我需要摆脱这种“function”。

到目前为止,我已经设法找到这个方法:

[DllImport("user32.dll")] static extern ushort GetAsyncKeyState(int vKey); public static bool IsKeyPushedDown(Keys keyData) { return 0 != (GetAsyncKeyState((int)keyData) & 0x8000); } 

但是方法IsKeyPushedDown发现在调用函数的时刻是否按下了键 – 所以我需要一个循环来测试密钥是否关闭。 问题是它仍然没有捕获所有的击键 – 我猜的循环太慢了。

第二个选择是覆盖ProcessCmdKey:

 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { // processing keys if (keyData == Keys.Left || keyData == Keys.Right || keyData == Keys.Up || keyData == Keys.Down) { return true; } else { return base.ProcessCmdKey(ref msg, keyData); } } 

这个效果非常好,但它受到重复延迟的影响,因此我的怪物在我的游戏中的移动就像:

我的问题有解决方案吗? 谢谢

编辑:我通过结合这两个程序解决了这个问题。 但这是非常难看的解决方案。 我仍然希望有更好的解决方案。

如果您希望更好地控制按下和释放按键之间发生的事情,则应该处理KeyDownKeyUp而不是ProcessCmdKey

在你的场景中最简单的事情就是在你的表单上有一个移动怪物的计时器。 触发KeyDown时启用计时器(并设置某种变量或指示如何移动怪物的deltaX和deltaY),然后在KeyUp时停止计时器。

编辑

作为一个例子(非常准确)

 public class MyForm : Form { private int deltaX; private int deltaY; private const int movementAmount = 10; private Timer movementTimer = new Timer(); public MyForm() { movementTimer.Interval = 100; // make this whatever interval you'd like there to be in between movements movementTimer.Tick += new EventHandler(movementTimer_Tick); } void movementTimer_Tick(object sender, EventArgs e) { myMonster.Location = new Point(myMonster.X + deltaX, myMonster.Y + deltaY); } protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); switch (e.KeyCode) { case Keys.Left: { deltaX -=movementAmount; } break; case Keys.Right: { deltaX += movementAmount; } break; case Keys.Up: { deltaY -= movementAmount; } break; case Keys.Down: { deltaY += movementAmount; } break; } UpdateTimer(); } protected override void OnKeyUp(KeyEventArgs e) { base.OnKeyUp(e); switch (e.KeyCode) { case Keys.Left: { deltaX += movementAmount; } break; case Keys.Right: { deltaX -= movementAmount; } break; case Keys.Up: { deltaY += movementAmount; } break; case Keys.Down: { deltaY -= movementAmount; } break; } UpdateTimer(); } private void UpdateTimer() { movementTimer.Enabled = deltaX != 0 || deltaY != 0; } }