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();
}
}
答案 0 :(得分:0)
你的代码有几个问题,我会一个接一个地通过它们。
首先,只要按住任何键,KeyDown事件就会每秒触发多次。
这意味着如果RunWorkerAsync();
在事件第二次触发之前未完成,您将收到InvalidOperationException
。
如果您之前按住某个键,请按键A,然后您尝试按住D键,即使同时按下两个键,新键码也将是D而不是A.您可以在记事本中测试此行为。
由于您使用的是WinForm,因此您无法访问Win32 Keyboard
包装器。您需要自己进行一些手动跟踪。
您可以使用HashSet<Keys>
来存储当前按下的键。您在KeyDown
事件中添加新密钥,并在KeyUp
事件中删除它们。然后,您可以通过列表进行迭代,以检查当前哪些键已关闭并采取相应措施。