http://www.microsoft.com/windowsxp/using/accessibility/characterrepeatrate.mspx-Windows中有一个用于设置重复延迟的选项。这意味着如果一个人持续按下该键,则在第一次击键与其他击键之间的延迟。我正在创建一种游戏,我需要摆脱这种“功能”。
到目前为止,我设法找到了这种方法:
[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);
            }
}
这确实很好,但是会受到重复延迟的影响,因此游戏中怪物的移动就像:
我的问题有解决方案吗?谢谢
编辑:我通过结合两个程序解决了问题。但这是非常丑陋的解决方案。我仍然希望有更好的解决方案。
您应该进行处理KeyDown,KeyUp而不是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;
    }
}