Фигура в C# WPF двигается неопределенным образом

Пишу игру в двух проектах: первый - меню(по сути основной), второй - экспериментальный(работа со спрайтами, движением и т.д.). Как только второй проект я посчитал уже законченным, то есть все, что я хотел реализовать - получилось, решил перенести код в первый. Но начав переписывать код связанный с движением, начались неполадки: создал Rectangle, который по сути является персонажем, которым ты играешь, после привязал KeyUp и KeyDown к кнопкам(код см. ниже), чтобы персонаж "двигался" при нажатии, но если установить KeyUp и KeyDown на кнопки "W" "A" "S" "D", то он не двигается, а если на стрелочки, то движение будет происходить, но отрывками, а после и вовсе кнопка будто зажимается и он продолжает свое движение уже за пределами карты. Сначала думал, что проблема в флагах, но ничего не нашел. После подумал о том, что второй проект я писал в главном окне, а первый(который с меню), у меня реализован с помощью пользовательского элемента управления, которые являются "окнами" меню, как и собственно "окном" с игрой, из этого вывел то, что фокус стоит на прошлом пользовательском элементе(они у меня работают по принципу Visible: нажал кнопку, и окно видно, нажал другую). Сам путь до игры состоит из: Главное меню(главное окно)->Подготовка к игре(пользовательский элемент)->Игра(еще один пользовательский элемент)

Game.XAML

<UserControl x:Class="TLC.Game"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:TLC"
             mc:Ignorable="d" 
             d:DesignHeight="1080" d:DesignWidth="1920">
    <Canvas Name="MyCanvas" KeyDown="KeyIsDown" KeyUp="KeyIsUp">
        <Canvas.Background>
            <ImageBrush ImageSource="/fone.png"/>
        </Canvas.Background>
        <Button x:Name="BackToMenu" Width="100" Height="100" Click="BackToMenu_Click" BorderBrush="{x:Null}" Foreground="{x:Null}">
            <Button.Background>
                <ImageBrush ImageSource="/free-icon-left-arrow-10559345.png"/>
            </Button.Background>
        </Button>
        <Label Name="TimerLabel" Content="0" FontFamily="Magma" FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center" Canvas.Left="750" Canvas.Top="5" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ></Label>
        <Rectangle x:Name="who" Width="100" Height="150" Canvas.Left="415" Canvas.Top="286" HorizontalAlignment="Left" VerticalAlignment="Top" Fill="White" Stroke="#FF006CFF" Focusable="True"></Rectangle>
        <Rectangle Name="ground" Width="1930" Height="300" Canvas.Top="695" VerticalAlignment="Top" HorizontalAlignment="Center"/>
        <Rectangle Name="tower" Width="100" Height="100"></Rectangle>
    </Canvas>
</UserControl>

Game.XAML.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace TLC
{
    public abstract class Object
    {
        public int health { get; set; }
        public Object() { }
        public Object(int health)
        {
            this.health = health;
        }
    }
    class Player : Object
    {
        public int speed { get; set; }
        public int damage { get; set; }
        public int force { get; set; }
        public bool attack { get; set; }
        public bool goLeft { get; set; }
        public bool goRight { get; set; }
        public bool isJump { get; set; }
        public Player() { }
        public Player(int health, int speed, int damage, bool attack, bool goLeft, bool goRight, bool isJump, int force) : base(health)
        {
            this.speed = speed;
            this.damage = damage;
            this.attack = attack;
            this.goLeft = goLeft;
            this.goRight = goRight;
            this.isJump = isJump;
            this.force = force;
        }
    }
    class Enemy : Object
    {
        public int speed { get; set; }
        public int damage { get; set; }
        public bool attack { get; set; }
        public bool goLeft { get; set; }
        public Enemy() { }
        public Enemy(int health, int speed, int damage, bool attack, bool goLeft) : base(health)
        {
            this.speed = speed;
            this.damage = damage;
            this.attack = attack;
            this.goLeft = goLeft;
        }
    }
    class Tower : Object
    {
        public Tower() { }
        public Tower(int health) : base(health)
        {

        }
    }

    public partial class Game : UserControl
    {
        DispatcherTimer gameTimer = new DispatcherTimer();

        Rect playerhitbox;
        Rect Groundhitbox;
        Rect towerhitbox;

        Player Mainplayer = new Player();
        Tower MainTower = new Tower(100);

        public Game()
        {
            InitializeComponent();
            MyCanvas.Focus();
            gameTimer.Tick += GameTimerEvent;
            gameTimer.Interval = TimeSpan.FromMilliseconds(20);
            StartGame();
            Mainplayer.speed = 10;
        }
        public void GameTimerEvent(object sender, EventArgs e)
        {
            //Canvas.SetTop(player, Canvas.GetTop(player) + Mainplayer.speed);
            if (Mainplayer.goLeft == true && Canvas.GetLeft(who) > 5)
            {
                Canvas.SetLeft(who, Canvas.GetLeft(who) - Mainplayer.speed);
            }
            if (Mainplayer.goRight == true && Canvas.GetLeft(who) + (who.Width + 20) < 1920)
            {
                Canvas.SetLeft(who, Canvas.GetLeft(who) + Mainplayer.speed);
            }

            playerhitbox = new Rect(Canvas.GetLeft(who), Canvas.GetTop(who), who.Width, who.Height);
            Groundhitbox = new Rect(Canvas.GetLeft(ground), Canvas.GetTop(ground), ground.Width, ground.Height);

            if (playerhitbox.IntersectsWith(Groundhitbox))
            {
                Canvas.SetTop(who, Canvas.GetTop(ground) - who.Height);
            }
        }
        private void KeyIsDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Left)
            {
                Mainplayer.goLeft = true;
            }
            if (e.Key == Key.Right)
            {
                Mainplayer.goRight = true;
            }
        }

        private void KeyIsUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Left)
            {
                Mainplayer.goLeft = false;
            }
            if (e.Key == Key.Right)
            {
                Mainplayer.goRight = false;
            }
        }
        private void BackToMenu_Click(object sender, RoutedEventArgs e)
        {
            Visibility = Visibility.Collapsed;
        }
        public void StartGame()
        {
            Canvas.SetLeft(who, 110);
            gameTimer.Start();
        }
    }
}

Ответы (0 шт):