2009-07-23 28 views
1

http://www.microsoft.com/windowsxp/using/accessibility/characterrepeatrate.mspx - Windows中有一个用于设置重复延迟的选项。这意味着如果持续按下按键,则第一次按键与其他按键之间的延迟。我正在创造一种游戏,我需要摆脱这个“功能”。如何摆脱C#中的字符重复延迟?

到目前为止,我设法找到了这种方法:



[DllImport("user32.dll")] 
static extern ushort GetAsyncKeyState(int vKey); 

public static bool IsKeyPushedDown(Keys keyData) 
{ 
    return 0 != (GetAsyncKeyState((int)keyData) & 0x8000); 
} 

但这种方法如果该键被按下AT调用函数的时刻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); 
      } 

} 

这个作品确实不错,但它与重复延时的影响,我的怪物在我的游戏,因此运动是这样的:

有没有解决的办法我问题? 谢谢

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

+0

检查我张贴的溶液。它比恢复PInvoke并将它与ProcessCmdKey一起黑客更加优雅。 – 2009-07-23 17:44:38

回答

4

如果您希望更好地控制按下和释放按键之间发生的情况,您应该处理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; 
    } 
} 
+0

实际上,我不想控制按下和释放按键之间会发生什么 - 我一直按住按键,结果是:<其他调用了ProcessCmdKey的其他调用(正常调用)> – 2009-07-23 15:40:17