代码之家  ›  专栏  ›  技术社区  ›  MartyIX

我怎样才能消除C中的字符重复延迟?

  •  1
  • MartyIX  · 技术社区  · 15 年前

    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);
    }
    

    但是iskeypheddown方法会在调用函数时发现是否按下了键——所以我需要一个循环来测试键是否关闭。问题是它仍然不能捕捉所有的击键-我想我的循环太慢了。

    第二个选择是覆盖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);
                }
    
    }
    

    这真的很好,但它会受到重复延迟的影响,因此我的游戏中怪物的移动方式如下:

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

    编辑:我把这两个过程结合起来解决了这个问题。但这是一个非常丑陋的解决方案。我还是希望有更好的解决办法。

    1 回复  |  直到 15 年前
        1
  •  4
  •   Adam Robinson    15 年前

    你应该处理 KeyDown KeyUp 而不是 ProcessCmdKey 如果您希望在按键和释放按键之间有更大的控制权。

    在你的场景中最简单的事情就是在你的身体上有一个定时器来移动怪物。启用计时器(并设置某种变量或表示如何移动怪物的Deltax和Deltay)的时间 按下 被触发,然后在 松开键 被解雇了。

    编辑

    举个例子(非常简单)

    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;
        }
    }