Отображение объекта

106
12 февраля 2021, 06:50

Есть часть кода игры типа Space Invaders:

using System;
using System.Collections.Generic;
using System.Linq;
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;
namespace Invasion_of_gooks
{
    public partial class MainWindow : Window
    {
        System.Windows.Threading.DispatcherTimer Timer;
        DateTime date = new DateTime();
        //создание объекта прямоугольник
        public Rectangle helicopter = new Rectangle();
        //координаты вертолёта
        public int x = 633;
        public int y = 500;
        public MainWindow()
        {
            InitializeComponent();
            //таймер
            Timer = new System.Windows.Threading.DispatcherTimer();
            Timer.Tick += new EventHandler(DispatcherTimer_Tick);
            Timer.Interval = new TimeSpan(0, 0, 1);
            Add_Helicopter();
        }   
        private void Start_Click(object sender, RoutedEventArgs e)
        {
            //делаем элементы меню неактивными
            Start.IsEnabled = false;
            Exit.IsEnabled = false;
            upgrades.IsEnabled = false;
            achievements.IsEnabled = false;
            //делаем элементы меню невидимыми
            Start.Visibility = Visibility.Collapsed;
            Exit.Visibility = Visibility.Collapsed;
            upgrades.Visibility = Visibility.Collapsed;
            achievements.Visibility = Visibility.Collapsed;
            Timer.Start();
        }
        private void DispatcherTimer_Tick(object sender, EventArgs e)
        {
            date = date.AddSeconds(1);
            stopwatch.Content = date.Hour.ToString() + " : " + date.Minute.ToString() + " : " + date.Second.ToString();
        }
        private void Add_Helicopter()
        {
            //установка цвета линии обводки и цвета заливки при помощи коллекции кистей
            helicopter.Stroke = Brushes.Black;
            helicopter.Fill = Brushes.SkyBlue;
            //параметры выравнивания
            helicopter.HorizontalAlignment = HorizontalAlignment.Left;
            helicopter.VerticalAlignment = VerticalAlignment.Center;
            //размеры прямоугольника
            helicopter.Height = 100;
            helicopter.Width = 100;
            helicopter.Margin = new Thickness(x, y, 0, 0);
            //добавление объекта в сцену
            can.Children.Add(helicopter);
            //отрисовка вертолётика
            ImageBrush helicopter_image = new ImageBrush
            {
                ImageSource = new BitmapImage(new Uri(@"pack://application:,,,/images/attack_helicopter_desert_camo.png", UriKind.Absolute))
            };
            helicopter.Fill = helicopter_image;
        }
        private void Key_Down(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                //если нажата стрелочка вверх, то координата вертолётика смещается вверх
                case Key.Up:
                    helicopter.RenderTransform = new TranslateTransform(x, y - 1);
                    y -= 1;
                    break;
                //если нажата стрелочка вправо, то координата вертолётика смещается вправо
                case Key.Right:
                    helicopter.RenderTransform = new TranslateTransform(x + 1, y);
                    x += 1;
                    break;
                //если нажата стрелочка вниз, то координата вертолётика смещается вниз
                case Key.Down:
                    helicopter.RenderTransform = new TranslateTransform(x, y + 1);
                    y += 1;
                    break;
                //если нажата стрелочка влево, то координата вертолётика смещается влево
                case Key.Left:
                    helicopter.RenderTransform = new TranslateTransform(x - 1, y);
                    x -= 1;
                    break;
                case Key.W:
                    helicopter.RenderTransform = new TranslateTransform(x, y - 1);
                    y -= 1;
                    break;
                //если нажата стрелочка вправо, то координата вертолётика смещается вправо
                case Key.A:
                    helicopter.RenderTransform = new TranslateTransform(x + 1, y);
                    x += 1;
                    break;
                //если нажата стрелочка вниз, то координата вертолётика смещается вниз
                case Key.S:
                    helicopter.RenderTransform = new TranslateTransform(x, y + 1);
                    y += 1;
                    break;
                //если нажата стрелочка влево, то координата вертолётика смещается влево
                case Key.D:
                    helicopter.RenderTransform = new TranslateTransform(x - 1, y);
                    x -= 1;
                    break;
            }
        }
    }
}

После нажатия любой из кнопок WASD (так же на стрелочках) helicopter исчезает, а должен менять свою координату и перемещаться. Координата почему-то не изменяется. Помогите исправить это. :(

Answer 1

Ваш Rectangle должен быть дочернем элементом панели.

Почитайте, например, здесь.

Для вашей логики, возможно, подойдет очищение контейнера (что-то в стиле 'ваш_canvas'.Children.Clear()) и последующее задание свойств Canvas.Top и Canvas.Left для заново добавленного объекта.

Это кривоватый, но бронебойный способ.

Answer 2

Проблема была в том, что в скобках

helicopter.RenderTransform = new TranslateTransform(x, y - 1);

нужно было указывать не выражение "координата вертолёта +- 1", а именно смещение, например

helicopter.RenderTransform = new TranslateTransform(+15, 0);

Так же, теперь в каждом тике таймера удаляется предыдущий отрисованный вертолёт и рисуется новый:

private void DispatcherTimer_Tick(object sender, EventArgs e)
    {
        date = date.AddSeconds(1);
        stopwatch.Content = date.Hour.ToString() + " : " + date.Minute.ToString() + " : " + date.Second.ToString() + date.Millisecond.ToString();
        can.Children.Remove(helicopter);
        Add_Helicopter();
    }

Теперь проблема в том, что вертолётик не перемещается плавно изначально. Сначала он делает скачёк по выбранной оси (например, на +15 по оси x) и небольшой скачёк по противоположной оси.

READ ALSO
C# Цикл For (при DataGridView)

C# Цикл For (при DataGridView)

Появилась проблема, есть код (ниже написан):

109
C# Получение Ip host mac локальной сети

C# Получение Ip host mac локальной сети

Нужно вывести все айдпи,хосты и мак адреса всей локальной сети

93
Добавление данных в DataGridView. Автоинкремент

Добавление данных в DataGridView. Автоинкремент

В базе данных (MS Access) таблица с двумя столбцами: Код и НазваниеКод на автоинкременте

88