如何在 winforms 中使用键盘沿对角线移动字符?
How to move a character diagonally using the keyboard in winfroms?
我的角色只能水平和垂直移动。我希望程序同时捕捉到两次击键,而不仅仅是一次。
我使用 Winforms.
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.A)
Player.Move(Direction.Left);
if (e.KeyCode == Keys.D)
Player.Move(Direction.Right);
if (e.KeyCode == Keys.W)
Player.Move(Direction.Up);
if (e.KeyCode == Keys.S)
Player.Move(Direction.Down);
Invalidate();
}
您可以使用GetKeyState
方法获取按键状态:
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern short GetKeyState(int keyCode);
public const int KEY_PRESSED = 0x8000;
public static bool IsKeyDown(Keys key)
{
return Convert.ToBoolean(GetKeyState((int)key) & KEY_PRESSED);
}
当您使用 IsKeyDown(Keys.A)
方法检查按键状态时 returns true
如果在检查状态时按下按键。
然后在每个按键按下事件中,您可以检查 A,W,D[ 的按键状态=40=]、S。您可以将这些键映射到二进制数中的位置,并根据以下 table:
计算有效组合
|S|D|W|A| Number | Direction |
------------------------------
|0|0|0|1| 1 | ← |
|0|0|1|0| 2 | ↑ |
|0|0|1|1| 3 | ↖ |
|0|1|0|0| 4 | → |
|0|1|1|0| 6 | ↗ |
|1|0|0|0| 8 | ↓ |
|1|0|0|1| 9 | ↙ |
|1|1|0|0| 12 | ↘ |
例子
以下示例假设表单上有一个标签,我们想用 A,W,[=32 移动标签=]D,S键:
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern short GetKeyState(int keyCode);
public const int KEY_PRESSED = 0x8000;
public static bool IsKeyDown(Keys key)
{
return Convert.ToBoolean(GetKeyState((int)key) & KEY_PRESSED);
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
var keyStates = new System.Collections.BitArray(new bool[]{
IsKeyDown(Keys.A), IsKeyDown(Keys.W),
IsKeyDown(Keys.D), IsKeyDown(Keys.S)});
var combination = new byte[1];
keyStates.CopyTo(combination, 0);
var c = label1; var d = 3;
switch (combination[0])
{
case 1:
c.Text = "←"; c.Left -= d; break;
case 2:
c.Text = "↑"; c.Top -= d; break;
case 3:
c.Text = "↖"; c.Left -= d; c.Top -= d; break;
case 4:
c.Text = "→"; c.Left += d; break;
case 6:
c.Text = "↗"; c.Left += d; c.Top -= d; break;
case 8:
c.Text = "↓"; c.Top += d; break;
case 9:
c.Text = "↙"; c.Left -= d; c.Top += d; break;
case 12:
c.Text = "↘"; c.Left += d; c.Top += d; break;
default:
c.Text = ""; break;
}
Invalidate();
}
我的角色只能水平和垂直移动。我希望程序同时捕捉到两次击键,而不仅仅是一次。 我使用 Winforms.
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.A)
Player.Move(Direction.Left);
if (e.KeyCode == Keys.D)
Player.Move(Direction.Right);
if (e.KeyCode == Keys.W)
Player.Move(Direction.Up);
if (e.KeyCode == Keys.S)
Player.Move(Direction.Down);
Invalidate();
}
您可以使用GetKeyState
方法获取按键状态:
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern short GetKeyState(int keyCode);
public const int KEY_PRESSED = 0x8000;
public static bool IsKeyDown(Keys key)
{
return Convert.ToBoolean(GetKeyState((int)key) & KEY_PRESSED);
}
当您使用 IsKeyDown(Keys.A)
方法检查按键状态时 returns true
如果在检查状态时按下按键。
然后在每个按键按下事件中,您可以检查 A,W,D[ 的按键状态=40=]、S。您可以将这些键映射到二进制数中的位置,并根据以下 table:
计算有效组合|S|D|W|A| Number | Direction |
------------------------------
|0|0|0|1| 1 | ← |
|0|0|1|0| 2 | ↑ |
|0|0|1|1| 3 | ↖ |
|0|1|0|0| 4 | → |
|0|1|1|0| 6 | ↗ |
|1|0|0|0| 8 | ↓ |
|1|0|0|1| 9 | ↙ |
|1|1|0|0| 12 | ↘ |
例子
以下示例假设表单上有一个标签,我们想用 A,W,[=32 移动标签=]D,S键:
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern short GetKeyState(int keyCode);
public const int KEY_PRESSED = 0x8000;
public static bool IsKeyDown(Keys key)
{
return Convert.ToBoolean(GetKeyState((int)key) & KEY_PRESSED);
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
var keyStates = new System.Collections.BitArray(new bool[]{
IsKeyDown(Keys.A), IsKeyDown(Keys.W),
IsKeyDown(Keys.D), IsKeyDown(Keys.S)});
var combination = new byte[1];
keyStates.CopyTo(combination, 0);
var c = label1; var d = 3;
switch (combination[0])
{
case 1:
c.Text = "←"; c.Left -= d; break;
case 2:
c.Text = "↑"; c.Top -= d; break;
case 3:
c.Text = "↖"; c.Left -= d; c.Top -= d; break;
case 4:
c.Text = "→"; c.Left += d; break;
case 6:
c.Text = "↗"; c.Left += d; c.Top -= d; break;
case 8:
c.Text = "↓"; c.Top += d; break;
case 9:
c.Text = "↙"; c.Left -= d; c.Top += d; break;
case 12:
c.Text = "↘"; c.Left += d; c.Top += d; break;
default:
c.Text = ""; break;
}
Invalidate();
}