Статьи

Узнайте о линейной кинематике

Изображение анимации с точки зрения векторов интуитивно понятно, но понимание векторной математики — это боль. В этом уроке я надеюсь облегчить эту боль и обеспечить решение проблем с анимацией, используя специально написанный класс Vector2D. Мы рассмотрим некоторые фундаментальные концепции линейной кинематики в эйлеровом подходе: смещение, скорость и ускорение. Затем мы создадим простое приложение с ним.


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


Все векторные величины имеют две составляющие: величину и направление.

Изображение вектора количества.

Изменение векторных величин относится к одному из следующих случаев:

  1. Смена направления
  2. Изменение величины
  3. Изменение как величины, так и направления
Изображение вектора количества.

Смещение, скорость и ускорение являются векторными величинами. Их определения следующие:

  • Смещение — вектор кратчайшего пути, указывающего от источника к месту назначения. Я определяю начало как точку (0, 0) и пункт назначения как местоположение частицы относительно этой точки. По сути, это относится к декартовой системе координат, реализованной Flash.
  • Скорость — Скорость — это смещение с течением времени.
  • Ускорение — Ускорение — это изменение скорости во времени.

Анимация ниже показывает смещение, как мы собираемся реализовать во Flash позже.


Скорость проиллюстрирована анимацией ниже. Обратите внимание, что скорость постоянна, что означает, что в этом сценарии ускорение отсутствует. Если скорость равна нулю, смещение будет оставаться постоянным во всем.


Ускорение иллюстрируется анимацией ниже. Примечание: кинематика подразумевает постоянное ускорение. Если ускорение меняется со временем, оно подпадает под тему динамики . Динамика — это изучение сил, которые вызывают ускорение с течением времени. Одной из таких сил является гравитация, и я написал пост об этой анимации .


Теперь, когда вы получили краткое представление о линейных кинематических величинах и смогли связать их с векторами, мы можем приступить к созданию нашего класса «Снаряд». Мы хотели бы, чтобы снаряд мог захватить все эти величины: смещение, скорость и ускорение — так, чтобы им можно было манипулировать на каждом кадре.

Ниже приведены данные, которые мы запишем в нашем классе снарядов:


После инициации этого класса Снаряда мы инициализируем упомянутые переменные и рисуем его графическое представление

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public function Projectile()
{
    //draw graphics
    this.draw();
 
    //init all vector quantities
    displace = new Vector2D(this.x, this.y);
    velo = new Vector2D(0, 0);
    acc = new Vector2D(0, 0);
}
 
protected function draw():void
{
    //drawing the arrowhead
    var height:Number = 30;
    var width:Number = 60;
    graphics.beginFill(0x0000FF);
    graphics.moveTo(0, 0);
    graphics.lineTo(width / -3, height / -2);
    graphics.lineTo(width / 2, 0);
    graphics.lineTo(width / -3, height / 2);
    graphics.lineTo(0, 0);
    graphics.endFill();
}

Ниже приведены методы доступа к нашим личным переменным — displace , velo , acc — в классе «Снаряд»


После обновления каждого кадра нам нужно обновить скорость (используя ускорение) и обновить смещение (используя указанную скорость). Это может быть достигнуто с помощью следующих функций. Чтобы получить подробное объяснение о добавлении Vector, посетите этот великий пост от Daniel Sidhon .


Нам также нужно будет обновить ориентацию Sprite. Это может быть достигнуто с помощью свойства rotation Sprite.

Я также реализовал статический класс Math2 , в котором я написал функцию, позволяющую легко преобразовывать единицы измерения градусов и радиан в угол назад и вперед.


Теперь, когда мы создали классы Projectile и Math2, мы можем начать кодировать наш основной класс. Нам также понадобится класс Vector2D, хотя подробное объяснение не включено в связи с вышеупомянутой статьей Даниэля Сидхона « Векторы « Я предполагаю, что читатели понимают класс Vector2D после прочтения. Тем не менее, если необходимы разъяснения, не стесняйтесь ответить на ваши вопросы.

Прежде всего нам нужно знать приватные переменные этого класса.


После инициализации Main будет запущена функция init . Эта функция создаст новый снаряд и установит его начальную скорость. Затем слушатели событий будут назначены.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
private function init(e:Event = null):void
{
    removeEventListener(Event.ADDED_TO_STAGE, init);
    // entry point
 
    b1 = new Projectile();
    stage.addChild(b1);
 
    //setting initial velocity
    b1.setVelo(5, Math2.radianOf(30));
 
    //setting event listeners
    b1.addEventListener(Event.ENTER_FRAME, proj_enterFrame);
    stage.addEventListener(KeyboardEvent.KEY_DOWN, handle_keyDown);
    stage.addEventListener(KeyboardEvent.KEY_UP, handle_keyUp);
}

Я определил пользовательский контроль как нажатия клавиш со стрелками вверх, влево, вниз и влево. После нажатия и отпускания этих клавиш переменные-флажки Main (Шаг 11) будут установлены в true и false. Основываясь на этих флагах, Векторными величинами будут манипулировать в каждом кадре. Обратите внимание, что я разделил элементы управления на манипуляторы с горизонтальной и вертикальной осями.


После обновления каждого кадра будет выполнен следующий код. Это долго, но не волнуйся; просто читайте дальше.


Обновление движения должно быть сделано в следующем порядке:

  1. Определите новое ускорение в соответствии с нажатием клавиши пользователя.
  2. Используя ускорение, обновите текущую скорость.
  3. Используя текущую скорость, обновите текущее смещение.
  4. Уточните смещение, чтобы удержать объект внутри границ.

Я выделил коды для легкой идентификации этих шагов.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private function proj_enterFrame(e:Event):void
{
    //define acceleration
    var accMag:Number = 0.1;
    if (UP) {
        b1.setAcc(accMag, Math2.radianOf(-90));
        b1.applyAcc();
    }
 
    else if (DOWN) {
        b1.setAcc(accMag, Math2.radianOf(90));
        b1.applyAcc();
    }
 
    if (LEFT) {
        b1.setAcc(accMag, Math2.radianOf(180));
        b1.applyAcc();
    }
 
    else if (RIGHT) {
        b1.setAcc(accMag, Math2.radianOf(0));
        b1.applyAcc();
    }
 
    //decelerate as nothing is pressed to simulate friction.
    if (UP + DOWN + LEFT + RIGHT == 0) {
        var currentVeloMag:Number = b1.getVelo().getMagnitude();
        var currentVeloAng:Number = b1.getVelo().getAngle();
 
        if(currentVeloMag > 1){
            b1.setAcc(accMag * -1, currentVeloAng);
            b1.applyAcc();
        }
    }
 
    b1.applyVelo();
 
    //restricting sprite to borders of the stage
    b1.getDisp().x = Math2.implementBound(0, stage.stageWidth, b1.getDisp().x);
    b1.getDisp().y = Math2.implementBound(0, stage.stageHeight, b1.getDisp().y);
 
    b1.animate();
    b1.orient();
}

Вы можете обнаружить, что между этими выделенными кодами есть другие функции. Кто они такие? Одним из них является применение другого вектора для замедления нашего снаряда, так как пользователь не нажимает ни на какие клавиши. Это применяется прежде, чем мы добавим скорость к нашему смещению.


Следующее — ограничить наш снаряд, чтобы он всегда оставался на сцене, иначе он вылетит за пределы экрана. Опять же, ImplementBound — это функция, которую я включил в статический класс Math2. Учитывая верхнюю границу, нижнюю границу и случайное значение, implementBound вернет значение, которое находится внутри границ.

После применения этих ограничений к нашему смещению (и только после этого) мы обновляем позицию Sprite с помощью этого значения смещения.


Прежде чем оставить этот спрайт таким, какой он есть, мы должны сориентировать его так, чтобы он всегда указывал в положение, в котором он движется, с помощью функции orient .


Теперь все готово к работе. Когда вы запустите эту часть, нажав Ctrl + Enter, вы увидите стрелку, которая постепенно замедляется, когда она направляется по диагонали вниз по экрану. Нажмите на четыре клавиши со стрелками, чтобы переместить стрелку вокруг. Не беспокойтесь о потере своей стрелы; это останется внутри вашего взгляда.


Эта статья должна познакомить вас с использованием векторов для анимации движения. Как только вы поняли кинематику, продолжайте читать мой пост о динамике . Дайте мне знать, как это происходит. Спасибо.