如何摆脱C#中的字符重复延迟? [英] How can I get rid of character repeat delay in C#?

查看:73
本文介绍了如何摆脱C#中的字符重复延迟?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

http://www.microsoft.com/windowsxp/using/accessibility /characterrepeatrate.mspx -Windows中有一个用于设置重复延迟的选项.如果一个人持续按下该键,则表示第一次击键与其他击键之间的延迟.我正在创建一种游戏,我需要摆脱这种功能".

http://www.microsoft.com/windowsxp/using/accessibility/characterrepeatrate.mspx - There's an option in Windows for setting repeat delay. It means the delay between first keystroke and the other ones if one keeps pressing the key. I'm creating a sort of game and I need to get rid of this "feature".

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

So far I've managed to find this method:



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

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

但是方法IsKeyPushedDown会在调用函数的那一刻找出是否按下了键-因此我需要一个循环来测试键是否按下.问题在于,它仍然无法捕获所有击键-我猜循环太慢了.

But the method IsKeyPushedDown finds out if the key is pressed AT THE MOMENT of calling the function - so I need a loop to test if key is down. Problem is that still it doesn't catches all keystrokes - I have too slow loop I guess.

第二个选择是覆盖ProcessCmdKey:

Second choice is overriding of 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);
            }

}

这确实很好,但是会受到重复延迟的影响,因此我的怪物在游戏中的移动就像:

this works really good but it's affected with repeat delay and therefore movement of my monster in my game is like:

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

Is there a solution for my problem? Thanks

我通过组合两个过程解决了这个问题.但这是非常丑陋的解决方案.我仍然希望有更好的解决方案.

I solved the problem by combining both procedures. But it's very ugly solution. I still hope there's better solution.

推荐答案

如果您想更好地控制按下和释放键之间的时间,应该处理KeyDownKeyUp而不是ProcessCmdKey

You should be handling KeyDown and KeyUp rather than ProcessCmdKey if you want greater control over what happens between the time a key is pressed and released.

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

The absolute easiest thing to do in your scenario would be to have a timer on your form that moves the monster. Enable the timer (and set some sort of variable or deltaX and deltaY that indicates how to move the monster) when KeyDown is fired, then stop the timer when KeyUp is fired.

修改

例如(非常准系统)

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

这篇关于如何摆脱C#中的字符重复延迟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆