Home > Software design >  Element motion on canvas with KeyDown event C# UWP
Element motion on canvas with KeyDown event C# UWP

Time:09-25

I am trying to create a game, where you control an element with the arrow keys, to move UP/DOWN/R/L. I used KeyDown and KeyUp events. I have class for positioning (‘Position’) where I keep my x and y axis positions and number of ‘steps’ - an 'int' variable the holds a number of pixels. I also have class (‘Goodie’) that heiress from Position class and managing my element’s movement. It worked excellent until I accidently deleted something but now I’m not sure what happened and my element (called ‘goodPlayer’) is not moving anymore at all (keyDown and keyDown not wroking).
This is my MainPage.XAML code:

    <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 code:

 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);
    }

}

CodePudding user response:

You can not directly add the KeyDown and KeyUp event to a grid because it will never receive focus. So you have to add another keyevent like this:

Add this to your MainPage.xaml.cs:

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

And then use the new events:

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;
     }
}
  • Related