【问题标题】:Smooth element motion on canvas with KeyDown event UWP使用 KeyDown 事件 UWP 在画布上平滑元素运动
【发布时间】:2016-11-21 09:03:33
【问题描述】:

我正在尝试创建一种宇宙飞船游戏,您可以在其中使用箭头键控制图像(显然是宇宙飞船的),以向上/向下/R/L 移动。 为此,我使用 CoreWindow.KeyDown 事件。

它实际上工作正常,但动作不够流畅。 每次我按下箭头键之一,图像然后: 1. 朝那个方向迈出一步 2.冻结,大约半秒(甚至更短) 3.然后继续前进,没有任何麻烦。 (“step”是一个“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”由于某种原因不允许这样做。

感谢您的帮助。

【问题讨论】:

    标签: c# xaml canvas uwp uwp-xaml


    【解决方案1】:

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

    【讨论】:

    • 为此我把谷歌翻了个底朝天。非常感谢!问题解决了:)
    猜你喜欢
    • 2012-12-20
    • 2012-09-17
    • 2018-09-05
    • 1970-01-01
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多