Опубликован: 07.11.2006 | Уровень: специалист | Доступ: платный
Лекция 2:

Представление сайта

Колебательное движение

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

В каждом кадре мы умножаем переменную speed на результат деления для уменьшения скорости. На графике ниже показано, как продолжается движение после прохождения конечной точки, и последующее возвращение объекта.


Скорость объекта увеличивается в пропорции с расстоянием, на котором он находится от конечной точки. Из рисунка видно, что сначала он стремительно ускоряется, проходит конечную точку и затем возвращается обратно. Амплитуда его колебаний около цели медленно уменьшается.

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

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

Окончательный эффект может быть в виде ожидаемого колебания вперед и назад около конечной точки и гораздо более плавного исчезновения, или эффекта резкой остановки.

  1. Это упражнение будет использовать те же основные установки, какие были настроены ранее с фильмом, размещенным на рабочем месте с именем ball_mc и отдельным слоем для кода. Мы также можем использовать некоторый код, который был применен ранее (функции, проверяющие расстояние, создающие следы и обрабатывающие событие mouseDown ), но он представляет собой лишь само движение, и нам необходимо изменить его.
    ball_mc.checkDistance = function() {
      if (Math.abs(this.targetX-this._x)<0.2 
       && Math.abs(this.targetY-this._y)<0.2) {
        this._x = this.targetX;
        this._y = this.targetY;
        delete this.onEnterFrame;
      }
    };
    
    ball_mc.duplicate = function() {
      var dupe = this.duplicateMovieClip 
        ("dupe"+this._parent.depth,
            this._parent.depth++);
      dupe.onEnterFrame = this._parent.diminish
    };
    
    function diminish(){
      // reduce scale gradually
      this._xscale = this._yscale-=2;
      //remove movieclip when scale goes below zero
      if (this._xscale <= 0) {
        this.removeMovieClip();
      }
    }
    
    ball_mc.onMouseDown = function() {
      this.targetХ = this._parent._xmouse;
      this.targetY = this._parent._ymouse;
      this.onEnterFrame = this.moveToMouse;
    };
  2. Единственное, что нам нужно добавить, это функция moveToMouse, переменные скорости и т.д. Сначала необходимо определить два наших параметра, которые мы будем называть acceleration (ускорение) и friction (колебание). Установим для них значения 12 и 0,8, несмотря на то, что у нас будет возможность изменить их позднее для достижения различных эффектов. Добавьте эти две строки перед определением функции, в верхней части кода:
    var acceleration = 12;
    var friction = 0.8;

    Итак, acceleration будет значением, на которое мы делим расстояние перед добавлением его к скорости нашего фильма, а friction будет являться значением, которое умножается на скорость каждого кадра по порядку для уменьшения быстроты движения.

    Мы проработаем код движения по оси x перед добавлением его в функцию moveToMouse.

  3. Прежде всего, мы создадим временную переменную для хранения расстояния между нашим фильмом и конечной точкой. Следующий код предназначен для функции moveToMouse.
    var xdif=this.targetX-this._x;
  4. Затем мы добавим результат деления этого значения к нашему значению xspeed (переменная, представляющая скорость фильма по оси x ):
    this.xspeed+=xdif/this._parent.acceleration;
  5. Затем умножаем переменную speed на переменную friction для уменьшения скорости. Если не делать этого, наш фильм будет колебаться около своей конечной точки, не приближаясь к ней. Это умножение означает, что амплитуда уменьшается с каждым разом. Если убрать эту строку из исходного кода нашего окончательного результата, фильм не остановится на своей конечной точке, а будет двигаться вперед-назад на одно и то же расстояние.
    this.xspeed*=this._parent.friction;
  6. Наконец, обновляем фильм, добавляя значение его скорости к положению на оси x:
    this._x+=this.xspeed

    Теперь мы объединяем все это в одну функцию moveToMouse, добавляя также вызовы дубликата и checkDistance. Ниже приведен полный код программы, как для оси x, так и для оси y:

    ball_mc.moveToMouse = function() {
    
      // calculate difference on x and у axes
      var xdif = this.targetX-this._x;
      var ydif = this.targetY-this._y;
    
      // increment speed values
      this.xspeed += xdif/this._parent.acceleration;
      this.yspeed += ydif/this._parent.acceleration;
    
      // dampen speed values
      this.xspeed *= this._parent.friction;
      this.yspeed *= this._parent.friction;
    
      // add speed values to x and у properties
      this._x += this.xspeed;
      this._y += this.yspeed;
    
      // create duplicate
      this.duplicate();
      // check if the movieclip has reached its target
      this.checkDistance();
    };
  7. Сохраните ваш фильм в файле swing.fla и запустите его. Вы увидите эффект колебаний, причем объект будет вращаться почти по кругу вокруг конечной точки:

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

Вообще говоря, чем ниже значение acceleration, тем быстрее будет сначала двигаться фильм, и чем ближе к единице значение friction, тем больше фильм будет колебаться вперед и назад. Некоторые значения могут сделать этот пример очень похожим на случай с уменьшением скорости, рассмотренный нами в первую очередь. Например, попробуйте ввести значения acceleration = 17 ; и friction = 0.4 ; и сохраните ваш фильм в файле swing02.fla. Разница в том, что у нас есть переменная, сохраняющаяся во время прохождения кадров, и фильм не изменяет моментально направление своего движения, как это было в случае с исходным уменьшением скорости движения, или движением по кадрам, и поэтому эти изменения происходят плавней.

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

Это более простой случай: все, что нам нужно, это вставить выражение if в нашу функцию для проверки того, является ли скорость достаточно малой после попадания расстояния в диапазон:

ball_mc.checkDistance = function() {
  // check that distance is within range
  if (Math.abs(this.targetX-this._x)<0.2 
    && Math.abs (this. targetY-this ._y) < 0.2) {

    // check that speed is nearly zero
    if(Math.abs(this.xspeed)<0.2 && Math.abs(this.yspeed) < 0.2) {
      this._x = this.targetX;
      this._y = this.targetY;
      delete this.onEnterFrame;
    }
  }
};

Приведенный выше сценарий, содержащийся в swing3.fla, теперь защищен от любых непредвиденных обстоятельств.


Вы можете использовать эти основные принципы в различных ситуациях, контролируя скорость объекта разными способами. Сейчас на скорость влияет положение конечной точки (что-то похожее на магнетизм), однако вы, например, могли бы нажать кнопку правого курсора и добавить 5 к значению xspeed. Это переместит объект сильно вправо перед тем, как его скорость будет уменьшаться до полной остановки.

Если вам интересны способы создания других типов движения, рекомендуем вам обратить внимание на уравнения замедления на сайте www.robertpenner.com. Используя эти уравнения, вы можете указывать количество кадров, которое необходимо для определенной продолжительности движения, и фильм будет замедлять свое движение от точки A до точки B. В дополнение к этому, вы можете изучить применение этих уравнений на www.gizma.com/easing. Если вам интересны эти уравнения, Chris Andrade из www.fifthrotation.com опубликовал документ, описывающий их вывод, по адресу http://www.fifthrotation.com/u2/parabolic_ease.zip.

Игорь Хан
Игорь Хан

у меня аналогичная ситуация. Однако, если взять пример из приложения (ball_motion_04_click for trial.fla) то след остается. при этом заметил, что в моем проекте в поле "One item in library" виден кружок, в то время как в приложенном примере такого кружка нет.

Вопрос знатокам, что не так?

Александр Коргапольцев
Александр Коргапольцев

объект созданый мной упорно не желает оставлять след(единственное что добился, так это то что шарик резво гоняется за курсором) функция duplicateMovieClip остаётся не активной, т.е. следа от объекта не остаётся, но если я тоже самый код вбиваю в учебный файл всё работает, не могу понять где я ошибаюсь и почему в документе созданном заново, не работает код начиная от функции duplicateMovieClip? 

Тамара Ионова
Тамара Ионова
Россия, Нижний Новгород, НГПУ, 2009
Магомед Алисултанов
Магомед Алисултанов
Россия, Волгоград, лицей 2