如何在 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();
}