keydown事件取消其他c#

时间:2017-11-28 15:34:47

标签: c# multithreading keydown

很抱歉再问一个可能的简单问题,但我一直在互联网上寻找这个解决方案,但我无法做到。我正在Highschool编程中完成最终项目。除了这个小部分我完成了所有工作。我有两个背景工人(每个玩家一个),我有keydown事件让这些背景工作者开启。这是代码:

if (e.keycode == Keys.D)
{
    p1f = true;
    bgwPlayerOne.RunWorkerAsync();
}
if (e.keycode == Left)
{
    p2f = true;
    bgwPlayerTwo.RunWorkerAsync();
}

好吧,所以我不得不输入它,因为它在我的另一台没有互联网的计算机上,但这是keydown事件中的代码。变量告诉后台worker在哪个if语句中做。但是,主要问题是每当我同时按下D和左箭头键时,在另一次点击之前停止的那一个停止并且最近的关键事件开始。当我以前使用计时器时,我没有遇到这个问题(我遇到了滞后问题所以我切换到了多线程)。如果对此有任何疑问请告诉我,任何帮助将不胜感激,谢谢!

更新*****

private void frmTankBattle_MapOne_KeyDown(object sender, KeyEventArgs e)
    {


            if (e.KeyCode == Keys.D)
            {
                p1f = true;
                bgwPlayerOne.RunWorkerAsync();

            }
            //System.Threading.Thread.Sleep(1);
            if (e.KeyCode == Keys.A)
            {
                p1b = true;
                bgwPlayerOne.RunWorkerAsync();
            }
            //System.Threading.Thread.Sleep(1);
            if (e.KeyCode == Keys.Left)
            {
                p2f = true;
                bgwPlayerTwo.RunWorkerAsync();
            }
            //System.Threading.Thread.Sleep(1);
            if (e.KeyCode == Keys.Right)
            {
                p2b = true;
                bgwPlayerTwo.RunWorkerAsync();
            }

            if (e.KeyCode == Keys.Space)
            {
                p1c = true;
                tmrPlayerOneCombat.Start();
            }


       // System.Threading.Thread.Sleep(1);
    }
private void frmTankBattle_MapOne_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.D)
        {
            p1f = false;
            p1b = false;
            bgwPlayerOne.CancelAsync();
        }
        if (e.KeyCode == Keys.A)
        {
            p1f = false;
            p1b = false;
            bgwPlayerOne.CancelAsync();
        }
        if (e.KeyCode == Keys.Left)
        {
            p2f = false;
            p2b = false;
            bgwPlayerTwo.CancelAsync();
        }
        if (e.KeyCode == Keys.Right)
        {
            p2f = false;
            p2b = false;
            bgwPlayerTwo.CancelAsync();
        }
    }

1 个答案:

答案 0 :(得分:0)

你的代码有几个问题,我会一个接一个地通过它们。

首先,只要按住任何键,KeyDown事件就会每秒触发多次。

这意味着如果RunWorkerAsync();在事件第二次触发之前未完成,您将收到InvalidOperationException

如果您之前按住某个键,请按键A,然后您尝试按住D键,即使同时按下两个键,新键码也将是D而不是A.您可以在记事本中测试此行为。

由于您使用的是WinForm,因此您无法访问Win32 Keyboard包装器。您需要自己进行一些手动跟踪。

您可以使用HashSet<Keys>来存储当前按下的键。您在KeyDown事件中添加新密钥,并在KeyUp事件中删除它们。然后,您可以通过列表进行迭代,以检查当前哪些键已关闭并采取相应措施。