繁体   English   中英

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

[英]Smooth element motion on canvas with KeyDown event UWP

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

它实际上工作正常,但运动不够平稳。 每当我按下其中一个箭头键时,图像就会出现:1。向该方向移动一步2.冻结半秒钟(甚至更少)3然后继续移动,没有任何问题。 (“步”是一个'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);
    }

顺便说一下,我创建了一些专用布尔值的原因,这些布尔值将在每个KeyDown事件中设置为“true”或“false”,而不是直接使用KeyDown事件,因为该分离允许元素(船舶图像)移动对角线,同时直接使用“args.VirtualKey == Windows.System.VirtualKey.SomeArrowKey”不允许它出于某种原因。

谢谢你的帮助。

如果你想创建一个游戏,你应该在游戏循环中移动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();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM