使用 KeyDown 事件在 canvas 上进行元素运动 C# UWP

Element motion on canvas with KeyDown event C# UWP

我正在尝试创建一个游戏,您可以在其中使用箭头键控制元素移动 UP/DOWN/R/L。我使用了 KeyDown 和 KeyUp 事件。 我有 class 用于定位('Position'),我在其中保留 x 和 y 轴位置和“步数”数量 - 'int' 变量包含多个像素。我也有 class ('Goodie') 那个来自 Position class 的女继承人,负责管理我元素的移动。 在我不小心删除了一些东西之前,它一直运行良好,但现在我不确定发生了什么,我的元素(称为“goodPlayer”)根本不再移动(keyDown 和 keyDown 不工作)。
这是我的 MainPage.XAML 代码:

    <Grid Background="#ADDFFF" KeyDown="Grid_KeyDown" KeyUp="Grid_KeyUp">
    <Canvas x:Name="cnvAddControls">
        <Rectangle x:Name="goodPlayer" Height="100" Width="100" Fill="Blue" />
        <Rectangle x:Name="badPlayer" Height="100" Width="100" Fill="Yellow"/>
    </Canvas>
</Grid>

class 'Position':

    public class Posotion
{

    double _imgTop;
    double _imgLeft;
    int _steps;

    public Posotion(double imgLeft, double imgTop, int steps=5)
    {
        _imgTop = imgTop;
        _imgLeft = imgLeft;
        _steps = steps;
    }
    public double ImgTop
    {
        get { return _imgTop; }
    }
    public double ImgLeft
    {
        get { return _imgLeft; }
    }
    public int Steps
    {
        get { return _steps; }
    }
}

class 'Goodie':

  public class Goodie : Posotion
{
    Random rand = new Random();
    
    bool goUp; 
    bool goDown;
    bool goLeft;
    bool goRight;
    bool jump;

    public Goodie(bool goUp, bool goDown, bool goLeft, bool goRight, bool jump, double imgLeft, double imgTop, int steps)
        : base(imgLeft, imgTop, steps)
    {
        this.goUp = goUp;
        this.goDown = goDown;
        this.goLeft = goLeft;
        this.goRight = goRight;
        this.jump = jump;
        
    }
    public void movePlayer(Rectangle goodPlayer, Canvas cnvAddControls)
    {
        if (goUp) moveUp(goodPlayer);
        if (goDown) moveDown(goodPlayer);
        if (goRight) moveRight(goodPlayer);
        if (goLeft) moveLeft(goodPlayer);
        if (jump) jumpRandom(goodPlayer, cnvAddControls); 
    }
    public void moveUp(Rectangle goodPlayer)
    {
        goodPlayer.SetValue(Canvas.TopProperty, ImgTop - Steps);
    }

    public void moveDown(Rectangle goodPlayer)
    {
        goodPlayer.SetValue(Canvas.TopProperty, ImgTop + Steps);
    }

    public void moveRight(Rectangle goodPlayer)
    {
        goodPlayer.SetValue(Canvas.LeftProperty, ImgLeft + Steps);
    }

    public void moveLeft(Rectangle goodPlayer)
    {
        goodPlayer.SetValue(Canvas.LeftProperty, ImgLeft - Steps);
    }
    public void jumpRandom(Rectangle goodPlayer, Canvas cnvAddControls)
    {
        double maxWidth = cnvAddControls.ActualWidth;
        double minWidth = 0;
        double randomWidth = (maxWidth - minWidth) * rand.NextDouble() + minWidth;
        goodPlayer.SetValue(Canvas.LeftProperty, randomWidth - goodPlayer.Width);

        double maxHeight = cnvAddControls.ActualHeight;
        double minHeight = 0;
        double randomHeight = (maxHeight - minHeight) * rand.NextDouble() + minHeight;
        goodPlayer.SetValue(Canvas.TopProperty, randomHeight - goodPlayer.Height);
       
    }

}

MainPage.xmal.cs代码:

 public sealed partial class MainPage : Page
{
    double imgTop;
    double imgLeft;
    int steps = 5;
    bool goUp, goDown, goLeft, goRight, jump;


    public MainPage()
    {
        this.InitializeComponent();
        Windows.UI.Xaml.Media.CompositionTarget.Rendering += CompositionTarget_Rendering;

        ImageBrush goodPlayerImg = new ImageBrush();
        goodPlayerImg.ImageSource = new BitmapImage(new Uri(this.BaseUri, "/goodieImg.png"));
        goodPlayer.Fill = goodPlayerImg;

        ImageBrush badPlayerImg = new ImageBrush();
        badPlayerImg.ImageSource = new BitmapImage(new Uri(this.BaseUri, "/baddiesImg.png"));
        badPlayer.Fill = badPlayerImg;

       ImageBrush backgroundImg = new ImageBrush();
        backgroundImg.ImageSource = new BitmapImage(new Uri(this.BaseUri, "/bgImg.jpg"));
        cnvAddControls.Background = backgroundImg;
    }



    private void Grid_KeyDown(object sender, KeyRoutedEventArgs e)
    {

        if (e.Key == Windows.System.VirtualKey.Up) goUp = true;
        else if (e.Key == Windows.System.VirtualKey.Down) goDown = true;
        else if (e.Key == Windows.System.VirtualKey.Left) goLeft = true;
        else if (e.Key == Windows.System.VirtualKey.Right) goRight = true;
        else if (e.Key == Windows.System.VirtualKey.J)
        {
            jump = true;
            goodPlayer.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
        }
    }

    private void Grid_KeyUp(object sender, KeyRoutedEventArgs e)
    {
        if (e.Key == Windows.System.VirtualKey.Up) goUp = false;
        else if (e.Key == Windows.System.VirtualKey.Down) goDown = false;
        else if (e.Key == Windows.System.VirtualKey.Left) goLeft = false;
        else if (e.Key == Windows.System.VirtualKey.Right) goRight = false;
        else if (e.Key == Windows.System.VirtualKey.J)
        {
            jump = false;
            goodPlayer.Visibility = Windows.UI.Xaml.Visibility.Visible;
        }
    }

    private void CompositionTarget_Rendering(object sender, object e)
    {
        Posotion goodiePosition = new Posotion(imgTop, imgLeft, steps);
        imgTop = (double)goodPlayer.GetValue(Canvas.TopProperty);
        imgLeft = (double)goodPlayer.GetValue(Canvas.LeftProperty);
        Goodie goodPlayerFunc = new Goodie(goUp, goDown, goLeft, goRight, jump, imgLeft, imgTop, steps);
        goodPlayerFunc.movePlayer(goodPlayer, cnvAddControls);
    }

}

您不能直接将 KeyDown 和 KeyUp 事件添加到网格,因为它永远不会获得焦点。 所以你必须像这样添加另一个关键事件:

将此添加到您的 MainPage.xaml.cs:

Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
Window.Current.CoreWindow.KeyUp += CoreWindow_KeyUp;

然后使用新事件:

private void CoreWindow_KeyUp(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs e)
{
    if (e.VirtualKey == Windows.System.VirtualKey.Up) goUp = false;
    else if (e.VirtualKey == Windows.System.VirtualKey.Down) goDown = false;
    else if (e.VirtualKey == Windows.System.VirtualKey.Left) goLeft = false;
    else if (e.VirtualKey == Windows.System.VirtualKey.Right) goRight = false;
    else if (e.VirtualKey == Windows.System.VirtualKey.J)
    {
        jump = false;
        goodPlayer.Visibility = Windows.UI.Xaml.Visibility.Visible;
    }
}

private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs e)
{
    if (e.VirtualKey == Windows.System.VirtualKey.Up) goUp = true;
    else if (e.VirtualKey == Windows.System.VirtualKey.Down) goDown = true;
    else if (e.VirtualKey == Windows.System.VirtualKey.Left) goLeft = true;
    else if (e.VirtualKey == Windows.System.VirtualKey.Right) goRight = true;
    else if (e.VirtualKey == Windows.System.VirtualKey.J)
    {
        jump = true;
        goodPlayer.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
     }
}