使用KeyDown事件UWP在画布上平滑元素运动

时间:2016-11-21 09:03:34

标签: c# xaml canvas uwp uwp-xaml

我正在尝试创造一种太空飞船游戏,用箭头键控制图像(显然是太空飞船),向上/向下/向下移动。 为此我使用了CoreWindow.KeyDown事件。

它实际上工作正常,但运动不够平稳。 每次按下其中一个箭头键,图像就会出现: 1.向该方向移动一步 2.冻结,半秒钟(甚至更少) 然后继续前进,没有任何问题。 (A"步骤",是一个' int'变量,它包含多个像素,比如20)。

当然,这无法运行游戏。当我按下其中一个箭头键而没有"半秒钟时,我想让船立即顺利移动。延迟。 这是我的代码:

public sealed partial class MainPage : Page
{
    double playerYAxisPosition;
    double playerXAxisPosition;
    int steps = 20;
    bool upMovement;
    bool downMovement;
    bool rightMovement;
    bool leftMovement;

    public MainPage()
    {
        this.InitializeComponent();
        Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
        Window.Current.CoreWindow.KeyUp += CoreWindow_KeyUp;
    }

    // Recognizes the KeyDown press and sets the relevant booleans to "true"
    private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args) {
        playerYPosition = (double) playerShip.GetValue(Canvas.TopProperty);
        playerXPosition = (double) playerShip.GetValue(Canvas.LeftProperty);

        if (args.VirtualKey == Windows.System.VirtualKey.Up) {
            upMovement = true;
        }
        else if (args.VirtualKey == Windows.System.VirtualKey.Down) {
            downMovement = true;
        }
        else if (args.VirtualKey == Windows.System.VirtualKey.Left) {
            leftMovement = true;
        }
        else if (args.VirtualKey == Windows.System.VirtualKey.Right) {
            rightMovement = true;
        }
        movePlayer();
    }

    // recognizes the KeyUp event and sets the relevant booleans to "false"
    private void CoreWindow_KeyUp(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args) {
        if (args.VirtualKey == Windows.System.VirtualKey.Up) {
            upMovement = false;
        }
        else if (args.VirtualKey == Windows.System.VirtualKey.Down) {
            downMovement = false;
        }
        else if (args.VirtualKey == Windows.System.VirtualKey.Left) {
            leftMovement = false;
        }
        else if (args.VirtualKey == Windows.System.VirtualKey.Right) {
            rightMovement = false;
        }
    }

    // Calls the movement Methods of the relevant direction
    private void movePlayer() {
        if (upMovement) {
            moveUp();
        }
        if (downMovement) {
            moveDown();
        }
        if (rightMovement) {
            moveRight();
        }
        if (leftMovement) {
            moveLeft();
        }
    }

    private void moveUp() {
        playerShip.SetValue(Canvas.TopProperty, playerYPosition - stepsToMove);
    }

    private void moveDown() {
        playerShip.SetValue(Canvas.TopProperty, playerYPosition + stepsToMove);
    }

    private void moveRight() {
        playerShip.SetValue(Canvas.LeftProperty, playerXPosition + stepsToMove);
    }

    private void moveLeft() {
        playerShip.SetValue(Canvas.LeftProperty, playerXPosition - stepsToMove);
    }

顺便说一句,我创造了一些专门的布尔值的原因,这些布尔将被设置为“真正的”#39;或者' false'在每个KeyDown事件上,并没有直接使用KeyDown事件,是因为该分离允许元素(船舶图像)也对角移动,同时使用" args.VirtualKey == Windows.System.VirtualKey.SomeArrowKey& #34;从某种原因直接不允许它。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

如果您想创建游戏,则应在游戏循环中移动playerShip。您可以使用DispatcherTimer或注册CompositionTarget.Rendering事件来创建游戏循环。

Windows.UI.Xaml.Media.CompositionTarget.Rendering += CompositionTarget_Rendering;

更改CoreWindow_KeyDown事件处理程序,如下所示:

private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
{
    if (args.VirtualKey == Windows.System.VirtualKey.Up)
    {
        upMovement = true;
    }
    else if (args.VirtualKey == Windows.System.VirtualKey.Down)
    {
        downMovement = true;
    }
    else if (args.VirtualKey == Windows.System.VirtualKey.Left)
    {
        leftMovement = true;
    }
    else if (args.VirtualKey == Windows.System.VirtualKey.Right)
    {
        rightMovement = true;
    }
}

接下来,在CompositionTarget.Rendering事件处理程序中移动您的船只。

private void CompositionTarget_Rendering(object sender, object e)
{
    playerYPosition = (double)playerShip.GetValue(Canvas.TopProperty);
    playerXPosition = (double)playerShip.GetValue(Canvas.LeftProperty);
    movePlayer();
}