我如何识别2个单独的按键作为一个键?

时间:2015-08-23 22:58:07

标签: c#

因此,对于我正在工作的游戏,我有一堆不同的键做不同的事情(例如w键使玩家查找,e键使角色向右看。)

我想知道有没有办法让W + D键让玩家看起来正确,即使这些键已被使用。

private void FrmGM_KeyDown(object sender, KeyEventArgs e)
    {            
        if (e.KeyCode == Keys.W)
        {
            picplayer.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.IPT_game_player1));
            bulletnumb = 1;
        }

        if (e.KeyCode == Keys.E)
        {
            picplayer.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.IPT_game_player2));
            bulletnumb = 2;
        }

        if (e.KeyCode == Keys.D)
        {
            picplayer.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.IPT_game_player3));
            bulletnumb = 3;
        }

        if (e.KeyCode == Keys.C)
        {
            picplayer.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.IPT_game_player4));
            bulletnumb = 4;
        }

        if (e.KeyCode == Keys.X)
        {
            picplayer.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.IPT_game_player5));
            bulletnumb = 5;
        }

        if (e.KeyCode == Keys.Z)
        {
            picplayer.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.IPT_game_player6));
            bulletnumb = 6;
        }

        if (e.KeyCode == Keys.A)
        {
            picplayer.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.IPT_game_player7));
            bulletnumb = 7;
        }

        if (e.KeyCode == Keys.Q)
        {
            picplayer.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.IPT_game_player8));
            bulletnumb = 8;
        }

这是按键的代码

4 个答案:

答案 0 :(得分:4)

KeyDown事件到达时将字母存储在集合中,并在KeyUp事件处理程序中将其删除。这样,您的KeyDown就可以“看到”是否按下了“随播密钥”:

private readonly ISet<char> keysCurrentlyDown = new HashSet<char>();

private void FrmGM_KeyDown(object sender, KeyEventArgs e) {            
    if (e.KeyCode == Keys.W)
    {
        if (keysCurrentlyDown.Contains('D')) {
            // Call some method to handle W+D
        } else {
            ...
        }
        keysCurrentlyDown.Add('W');
    } else if (e.KeyCode == Keys.D)
    {
        if (keysCurrentlyDown.Contains('W')) {
            // Call some method to handle W+D
        } else {
            ...
        }
        keysCurrentlyDown.Add('D');
    }
    ...
}
private void FrmGM_KeyUp(object sender, KeyEventArgs e) {            
    if (e.KeyCode == Keys.W) {
        keysCurrentlyDown.Remove('W');
    } else if (e.KeyCode == Keys.D) {
        keysCurrentlyDown.Remove('D');
    } ...
}

}

答案 1 :(得分:3)

这类事情的第一道攻击就是确保每个键可以同时激活,并且每个键的效果组合都有你想要的结果。如果您遵循该方法,您的代码将更易于维护且更易于编写,而不是尝试特殊情况下的组合键输入。

例如,您可以拥有一组代表当前键状态的标志,然后在游戏的帧更新中,检查这些标志并将字符状态设置为正确的事物(即不是在键中设置特定图像处理自己,正如你现在所做的那样。)

所以你可以有这样的标志:

bool lookUp, lookRight, lookDown, lookLeft;

然后 W 的键入将设置lookUp标志,而同一键的键入将清除该标志。同样例如对于 D ,对于lookRight标志。

然后在游戏框架更新中,检查标志。如果同时设置了lookUplookRight,则使用“向上和向右”图形。如果只设置了一个或另一个标志,则使用简单的“向上看”或“向右看”图形。同样适用于其他键及其组合。您甚至可以解析lookUplookDown,或lookLeftlookRight,无论默认图形是什么(即,好像用户没有按任何键)。


请注意,如果您愿意使用p / invoke,则可以使用GetAsyncKeyState()函数,甚至不必担心按键事件。只需在每次更新游戏帧之前检查按键状态,然后根据当前键盘状态更新视觉效果。这样,您可以让Windows执行所有关键状态跟踪,并且您不会浪费时间跟踪无关紧要的关键状态(例如,如果用户对帧之间的键状态进行多次更改)。


也就是说,如果你不能/不会做上述任何一项,那么是......你需要做的就是先检查一下这个组合(也就是说,你们两个都没有按键,而没有按键对于组合中最初按下的键。)

请注意,采用该方法意味着您仍然会按下第一个按键的效果,然后必须切换到组合效果。

答案 2 :(得分:0)

使用

PresentationCore.dll WindowsBase.dll 作为项目中的参考

PresentationCore.dll有一个键盘 - 类,而WindowsBase.dll有一个键 - 类。

然后:

    using System;
    using System.Windows.Forms;
    using System.Windows.Input;

            namespace ViewTest
            {
                public partial class ViewTest : Form
                {
                    private void ViewTest_KeyDown(object sender, KeyEventArgs e)
                    {
                        if (Keyboard.IsKeyDown(System.Windows.Input.Key.W) && 
                            Keyboard.IsKeyDown(System.Windows.Input.Key.D))
                        {
                            // do something
                        }
                    }
            }

这是一种简单的方法:)

答案 3 :(得分:-1)

请注意覆盖ProcessCmdKey

protected override bool ProcessCmdKey(ref Message m, Keys k)
{
    if (k == (Keys.Control | Keys.D))
    {
        MessageBox.Show("CTRL+D");

        return true;
    }

    return base.ProcessCmdKey(ref m, k);
}