WPF: перевод холста под углом - PullRequest
2 голосов
/ 10 февраля 2009

Применительно к этой программируемой игре Я сейчас строю.

Важно: прокрутите вниз, чтобы увидеть [Редактировать]

Некоторые из методов, которые пользователь может вызывать в моей игре, будут методами, которые будут выполнять преобразование преобразования в робота (в основном, Canvas).

Из метода перемещения я знаю направление (угол), под которым будет стоять робот в данный момент, а также знаю длину пикселей, которые робот хочет переместить.

Теперь проблема, с которой я сталкиваюсь, заключается в том, как перевести холст (по таймеру) для перемещения под его текущим углом?

альтернативный текст http://img8.imageshack.us/img8/3606/robottranslatemovementfu3.jpg

Должны быть некоторые математики, которые мне здесь не хватает, но я просто не могу понять, что нужно делать в каждом такте Таймера.

Вот метод, который вызывается, который содержит таймер, который будет тикать каждые 5 миллисекунд, анимировать движение:

public void Ahead(int pix)
    {
        eventQueue.Enqueue((TimerDelegate)delegate(DispatcherTimer dt)
        {
            /* Available Variables:
            Translate_Body.X <= Current Robot Location on X-axis
            Translate_Body.Y <= Current Robot Location on Y-axis
            Bot.Body <= The Canvas that needs to be translated (moved)

            To translate the robot, I just basically do this:
                Translate_Body.X++; or Translate_Body.YY++; to increment, or -- to decrement ofcourse

            Now I need to figure out the logic on when to increment (or decrement, according to the angle I suppose) the Y and X
            */

            IsActionRunning = true;
            dt.Tick += new EventHandler(delegate(object sender, EventArgs e)
            {
                lock (threadLocker)
                {
                     //The logic needs to happen in here, with each timer tick.
                     //so with each timer tick, the robot is moved on pixel according to its angle.
                     //Then I need to make a condition that will indicate that the robot has arrived at its destination, and thus stop the timer.
                }
            });    
            dt.Start();
        });
    }

[ВАЖНОЕ РЕДАКТИРОВАНИЕ]

Теперь я изменил свою логику, чтобы использовать WPF BeginAnimation вместо тикера для анимации. Так что теперь мне не нужно вычислять новые координаты на каждом тике, я просто предоставляю конечные координаты, и BeginAnimation переведет их за период времени:

public void Ahead(int pix)
    {
        eventQueue.Enqueue((TimerDelegate)delegate
        {

            Animator_Body_X.From = Translate_Body.X;
            Animator_Body_X.To = //The end X-coordinate
            Translate_Body.BeginAnimation(TranslateTransform.XProperty, Animator_Body_X);

            Animator_Body_Y.From = Translate_Body.Y;
            Animator_Body_Y.To = //The end Y-coordinate
            Translate_Body.BeginAnimation(TranslateTransform.YProperty, Animator_Body_Y);
        });
    }

Итак, теперь с учетом угла (0-359), на котором холст в настоящее время вращается, начиная с координат x и y (от того, где холст находится в данный момент) и расстояния, как рассчитать конечные координаты? 1039 *


ОБНОВЛЕНИЕ: Решение

Ответы [ 2 ]

1 голос
/ 10 февраля 2009

Чтобы помочь с математикой:

Если вы хотите переместиться на d расстояния в пикселях за t секунд, вам нужно будет двигаться в среднем x / t (пикселей / секунд).

Для этого вам нужно будет сохранить время начала вашей анимации (start_time).

В каждом такте таймера вычислять процент выполненной анимации:

percent_complete= (now - start_time) / t

Умножьте процент_полного на расстояние, которое вы хотите переместить, чтобы получить расстояние, которое вы должны быть от того, где вы начали (d_now). Не забывайте отслеживать начальное расстояние при запуске анимации.

d_now = percent_complete * d

Значения x и y робота для текущего тика таймера могут быть вычислены следующим образом:

x = d_now * cos(heading) + start.x
y = d_now * sin(heading) + start.y

Вам может понадобиться настроить признаки вещей, но это суть этого. Не говоря уже о том, не предусмотрены ли в WPF базовые процедуры анимации? Я никогда не использовал это, но это было мое впечатление. Link .

0 голосов
/ 14 марта 2009

Решение

Благодаря помощи Энди Микулы и Кэмерона МакФарланда , он наконец-то работает как задумано.

А вот и рабочий код:

double headingRadians = Heading * (Math.PI / 180);

Animator_Body_X.From = Translate_Body.X;
Animator_Body_X.To = Math.Sin(headingRadians) * pix + Translate_Body.X;
Translate_Body.BeginAnimation(TranslateTransform.XProperty, Animator_Body_X);

Animator_Body_Y.From = Translate_Body.Y;
Animator_Body_Y.To = ((Math.Cos(headingRadians) * pix) * -1) + Translate_Body.Y;
Translate_Body.BeginAnimation(TranslateTransform.YProperty, Animator_Body_Y);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...