2

我目前正在开发一个作为 WinForms 项目的小游戏。游戏场是由玩家(一个单独的类)可以继续前进的瓷砖网格构建的。我希望玩家使用箭头键移动并为其设置了一个事件处理程序,但它似乎从未被调用过。

(最小化)播放器类,它为 KeyEventArgs 实现 System.Windows.Forms 包:

public class Player : MovableObject
{
    public Player(Playtile position) : base(position)
    {
        EntityColor = ElementColors.PlayerColor;
        PostConstructor(position);
    }

    /// <summary>
    /// Reads keypress via eventhandler KeyEventArgs (key down). 
    /// </summary>
    private void ReadKeyDown(object sender, KeyEventArgs e)
    {
        switch (e.KeyCode)
        {
            case Keys.Up:
                // move up.
                break;
            case Keys.Right:
                // move right.
                break;
            case Keys.Down:
                // move down.
                break;
            case Keys.Left:
                // move left.
                break;
        }
    }
}

目前,ReadKeyDown 永远不会被调用。我如何实际将该 KeyEventDown 事件分配/绑定到播放器,以便它实际上在按键时调用该方法?

C# 中的 KeyEventArgs似乎只是说this.KeyDown += ReadKeyDown;,但它不会将 KeyDown 识别为任何东西,也不会给我一个可能缺少的程序集引用。

4

2 回答 2

1

KeyDown是其中的一员,Control因此在您的情况下,您可以在Form.

如下所示:

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
        textBox1.KeyDown += TextBox1_KeyDown;
    }

    private void TextBox1_KeyDown(object sender, KeyEventArgs e)
    {
    }
}

完整示例见官方文档:

https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.control.keydown?view=netframework-4.7.2

现在,您可以做的是在收到此类事件后调用目标类中的方法:

public class MyClass
{
    public void OnKeyDown(KeyEventArgs e)
    {
        // ...
    }
}

public partial class Form2 : Form
{
    MyClass _instance = new MyClass();

    public Form2()
    {
        InitializeComponent();
        textBox1.KeyDown += TextBox1_KeyDown;
    }

    private void TextBox1_KeyDown(object sender, KeyEventArgs e)
    {
        _instance.OnKeyDown(e);
    }
}
于 2019-04-12T00:46:01.147 回答
0

KeyDown您可以直接在课堂上订阅该事件:

public Player(Playtile position, Form form) : base(position) // <--- form parameter
{
    EntityColor = ElementColors.PlayerColor;
    PostConstructor(position);
    form.KeyDown += ReadKeyDown; // <--- subscribing to the event
}

不过有一个问题。现在表单包含对您的Player对象的引用,并且在关闭表单之前不会对对象进行垃圾收集。如果 Player 的生命周期与表单的生命周期相同,这不是问题。但是,如果您创建了许多短期播放器,那么您应该在不再需要它们时取消订阅表单的事件,方法是向播放器添加如下方法:

public void Dispose(Form form)
{
    form.KeyDown -= ReadKeyDown;
}

...并Dispose在您处置播放器对象时调用。

于 2019-04-12T04:14:12.670 回答