如何将箭头键分配给C#中的按钮



现在,我正在制作游戏和角色以移动玩家。我只是编程的初学者。

有8个按钮,每个按钮都朝着一个方向。例如,这是我的程序

private void btnUp_Click(object sender, EventArgs e)
{
    //move up
    y = y - 1;
    MovePlayer();
    UpdateLabelLocation();
}
public void MovePlayer()
{
    picPlayer.Location = new Point(x, y);
}
public void UpdateLabelLocation()
{
    lblLocation.Text = "Location: (" + x + ", " + y + ")";
}

我想在上下,向下,左或右键时使其移动。另外,如果可能的话,我想做到这一点,以便当我同时向右按下时,它会触发这一点:

private void btnRightUp_Click(object sender, EventArgs e)
{
    //move player
    y = y - 1;
    x = x + 1;
    MovePlayer();
    UpdateLabelLocation();
}

我感谢帮助。

您本质上要做的是创建自己的简单游戏引擎。正如评论员所指出的那样,最好使用现有的游戏引擎(例如Unity)。

也就是说,如果您真的想继续这样做,我强烈建议您将Click处理程序中的代码移至方法中。这减少了代码重复。即。

private void DownButton_Click(...)
{
    MovePlayer(0, 1);
}
private void UpButton_Click(...)
{
    MovePlayer(0, -1);
}
public void MovePlayer(float xStep, float yStep)
{
    x += xStep;
    y += yStep;
    MovePlayer();
    UpdateLabelLocation();
}

要向下移动并离开,您会致电MovePlayer(-1, 1);

要向上移动,您要致电MovePlayer(1, -1);

接下来,您需要响应按键事件。即。

public void Form_KeyPress(object sender, KeyPressEventArgs args)
{
    switch (args.KeyChar) {
        case 'a': // Left
            args.Handled = true;
            MovePlayer(-1, 0);
            break;
        case 'd': // Right
            args.Handled = true;
            MovePlayer(1, 0);
            break;
        case 'w': // Up
            args.Handled = true;
            MovePlayer(0, -1);
            break;
        case 's': // Down
            args.Handled = true;
            MovePlayer(0, 1);
            break;
    }
}

请注意,如果您有另一个接受键盘输入(例如TextBox)的控件,它将截取键按。要解决这个问题,请使用键盘浏览迫使窗口首先预览输入。args.Handled = true阻止了代码后从路由到子控制的事件。

不幸的是,Winforms并未同时记录多个键,因此仅使用按键不足以处理角移动。您可以通过连接到键盘和钥匙来解决这个问题,但这比价值还多。

这是一个更强大的解决方案。请记住以下条件不是安全的,因此,如果您打算引入其他线程,则需要使用适当的锁定。

HashSet<KeyCode> state = new HashSet<KeyCode>();
float speed = 120; // 120 pixels/second.
private void Form_KeyDown(object sender, KeyEventArgs args)
{
    var key = args.KeyCode;
    state.Add(key);
    // Fire pressed when a key was up.
    if (!state.Contains(key)) {
        state.Add(key);
        OnKeyPressed(key);
    }
}
private void Form_KeyUp(object sender, KeyEventArgs args)
{
    var key = args.KeyCode;
    state.Remove(key);
    // Fire release when a key was down.
    if (state.Contains(key)) {
        state.Remove(key);
        OnKeyReleased(key);
    }
}
// Runs when key was up, but pressed just now.
private void OnKeyPressed(KeyCode key)
{
    // Trigger key-based actions.
}
// Runs when key was down, but released just now.
private void OnReleased(KeyCode key)
{
    // Trigger key-based actions, but on release instead of press.
}
private bool IsDown(KeyCode key)
{
    return state.Contains(key);
}
// Trigger this periodically, at least 20 times a second(ideally 60).
// An option to get you started is to use a windows timer, but 
// eventually you'll want to use high precision timing instead.
private void Update()
{
    var deltaTime = // Calculate the seconds that have passed since the last update. 
    // Describing it is out of the scope of this answer, but see the links below.
    // Determine horizontal direction. Holding both 
    // A & D down cancels movement on the x-axis.
    var directionX = 0;
    if (IsDown(KeyCode.A)) {
        directionX--;
    }
    if (IsDown(KeyCode.D)) {
        directionX++;
    }
    // Determine vertical direction. Holding both 
    // W & S down cancels movement on the y-axis.
    var directionY = 0;
    if (IsDown(KeyCode.W)) {
        directionY--;
    }
    if (IsDown(KeyCode.S)) {
        directionY++;
    }
    // directionX & directionY should be normalized, but 
    // I leave that as an exercise for the reader.
    var movement = speed * deltaTime;
    var offsetX = directionX * movement;
    var offsetY = directionY * movement;
    MovePlayer(offsetX, offsetY);
}

您可以看到,涉及很多。如果您想要更多细粒度的时机,请查看本文。最终,您需要过渡到游戏循环,但这是此答案范围的另一个话题。

相关内容

  • 没有找到相关文章

最新更新