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

Анимация и интерактивность Drawing API

Анимация рисунков

Беспорядочные линии выглядят довольно занимательно, но они едва ли являются примером программированной анимации. С помощью API можно реализовать несравнимо более интересные эффекты. Так как числа являются единственными параметрами для отправки в функции рисования, довольно легко создавать анимированные рисунки в фильмах, просто изменяя числа, отправляемые в каждом кадре. Вы также можете легко изменить частоты смены кадров для анимации, лишь вызывая функцию рисования на установленных интервалах (с использованием подходящего и соответствующим образом названного setInterval).

Единственный "фокус" в анимации с помощью рисования API состоит в получении значений для ваших функций. Сначала создадим несложный инструмент, который поможет нам выполнить эту задачу. Это будет небольшой фильм для рисования линий на рабочем столе. Каждый рисунок будет представлять собой буфер перемещаемого изображения. После завершения создания рисунков будет происходить считывание в окне Output координат, необходимых для воссоздания рисунков с помощью рисования API. (Изучите файл API_animation.swf, находящийся на компакт-диске.)

Генератор сцен

  1. Создайте новый фильм с именем celMaker.fla и добавьте следующий код в первый кадр слоя по умолчанию.
    startDraw = function () {
      shapes [shapeNum] = [];
      this.moveTo(this._xmouse, this._ymouse);
      this.onMouseMove = draw;
    };
    stopDraw = function () {
      delete this.onMouseMove; 
      shapeNum++;
    };
    draw = function () {
      this.lineTo(this._xmouse, this._ymouse);
      shapes[shapeNum].push(Math.round(this._xmouse)+", "+
      КMath.round (this._ymouse) );
    };

    Здесь мы создаем три небольших "черновых" функции для поддержки рисования. startDraw перемещает карандаш на нашу текущую позицию мыши и устанавливает функцию draw на выполнение при каждом движении мыши. shapes является массивом для хранения позиций мыши.

    stopDraw удаляет функцию рисования из элемента управления onMouseMove и увеличивает число фигур на 1 (перед каждой новой фигурой нужна функция moveTo ).

    draw является нашей текущей функцией рисования, которая просто использует метод lineTo для рисования линии. Она также записывает позицию мыши в массив shapes таким образом, что мы впоследствии сможем вставлять эти значения напрямую в код при копировании и вставке из окна Output. Координаты _x и _y в (50, 100) будут форматированы в виде строки типа 50, 100. При трассировке кода в следующем шаге, мы сможем вставлять это значение прямо в аргументы lineTo.

  2. Добавьте следующую функцию.
    listVars = function () {
      code = "shape"+layerNum+" = function() {"+newline;
      code += " this.clear();"+newline;
      code += " this.lineStyle(2, 0, 100);"+newline;
      for (var i = 0; i<shapes. length; i++) {
        code += "this.moveTo("+shapes[i] [0]+");"+newline;
        for (var j = 1; j<shapes[i].length; j++) {
          code += " this.lineTo("+shapes[i][j]+");"+newline;
        } 
      }
      code += "}";
      trace(code); 
      makeLayer(); 
    };

    listVars впоследствии будет просто просматривать наши массивы и выдавать нужный код. Я часто устанавливаю такие методы трассировки для автоматической генерации всего длинного кода. Все, что в данном случае выполняют эти строки - записывают координаты в строки, которые отформатированы для копирования и вставки прямо в панель Actions. Например, при трассировке строки code в конце функции можно отправить в окно Output следующее.

    shape1 = function() {
       this.clear();
      this.lineStyle(2, 0, 100);
       this.moveTo(50, 100); 
      this.lineTo(100, 200);
    };
    shapes.push("shape1") ;

    После этого мы сможем вставить этот код в область Script панели Actions, причем он уже будет отформатирован соответствующим образом, поэтому синтаксических ошибок не возникнет. Довольно удобно.

  3. Добавьте эту последнюю функцию, которая будет создавать отдельные анимационные сцены посредством затемнения всех предыдущих рисунков.
    makeLayer = function () {
      delete layer.onMouseDown; 
      delete layer.onMouseUp;
      layer = this.createEmptyMovieClip("layer"+layerNum, layerNum);
      layerNum++;
      layer.lineStyle(2, 0, 100);
      layer.moveTo(150, 100);
      layer.beginFill(0xFFFFFF, 50);
      layer.lineTo(400, 100); 
      layer.lineTo(400, 300); 
      layer.lineTo(150, 300); 
      layer.lineTo(150, 100); 
      layer.endFill(); 
      shapes = []; 
      shapeNum = 0;
      layer.onMouseDown = startDraw; 
      layer.onMouseUp = stopDraw;
    };

    makeLayer - это своеобразный мини-Photoshop. Каждый раз при завершении анимационной сцены он будет создавать новый слой поверх ваших предыдущих сцен, чтобы можно было начать создание нового рисунка. Каждая сцена имеет прозрачность 50%, поэтому в итоге получается интересный эффект "многослойности". Функция также заново инициализирует массив shapes (который будет содержать координаты рисунков) и переменную shapeNum, которая будет содержать число фигур, изображенных на определенном слое. Так как мы создаем новый слой, это значение устанавливается на 0.

  4. Эти последние несколько строк кода обеспечивают выполнение всего упомянутого.
    layerNum = 0;
    _root.onKeyDown = listVars; 
    Key.addListener(_root); 
    makeLayer();

    Здесь мы инициализируем исходные переменные и устанавливаем главный фильм на прослушивание события keyPress. Метод addListener является новой полезной командой, позволяющей объектам принимать информацию о событиях, даже если они не были изначально настроены на эту возможность. Фильмы не "слышат" автоматически события клавиш, такие как keyDown и keyUp, однако мы можем добавить эту функциональность определенным инстансам с помощью addListener. Здесь мы настроили _root на прослушивание всех событий, связанных с объектом Key. После этого последняя строка создает первый слой, и можно приступать к работе.

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


  6. Сохраните фильм и оставьте его открытым, так как мы к нему сейчас вернемся.
Игорь Хан
Игорь Хан

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

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

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

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

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