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

Интерфейсы AсtionScript

  1. Теперь мы можем присвоить функцию.
    trigger.onKeyDown = shoot;

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

  2. Теперь можно приступить к определению нашей функции.
    function shoot() {
        currBullet_mc = _root.attachMovie("bullet", "bullet"+i, i);
        currBullec_mc._x = 275;
        currBullet_mc._y = 400;
        currBullet_mc.onEnterFrame = bulletMove;
        i++;
        if (i>9) {
          i = 0;
        }
      }

    Эта функция сначала присваивает инстанс bullet к _root. Она дает инстансу имя "bullet"+i. Мы добавляем строку в начале файла, приравнивающую i к нулю. Таким образом, наша первая пуля получит имя bullet0. В конце функции i увеличивается, поэтому при следующем выстреле именем пули будет bullet1. Мы также используем i для установки новой глубины фильма. Необходимо увеличивать глубины "метких" пуль, так как два фильма не могут существовать на одной и той же глубине. Они также не могут иметь одинаковых имен, если они находятся на одной и той же временной диаграмме. После этого мы добавляем небольшое выражение if. Оно сбрасывает i на ноль, если его значение превышает 9, поэтому на экране никогда не будет одновременно больше десяти пуль.

    Далее мы устанавливаем два параметра. Если бы мы знали полное имя фильма, мы могли бы использовать обозначение точками и написать _root.bullet0._x=275. Но так как i будет каждый раз меняться, нам нужно найти способ ссылки на это значение, независимо от его величины. В дополнение к обозначению точками, мы можем использовать обозначение массивами, добавляя строку в скобках. Строка является именем адресуемого объекта. Преимуществом этого метода является то, что строка может быть создана динамически. Следовательно, мы можем написать _root ["bullet"+i] для ссылки на фильм, именем которого является "bullet"+i. Однако существует еще более удачный способ. Он заключается в том, что при использовании действия attachMovie будет возвращаться ссылка на только что примененный фильм. Она будет записываться во временную переменную currBullet_mc (для текущей пули). Это позволит нам настраивать параметры без надобности ввода всех скобок и кавычек. Этот способ также несколько быстрее. Мы устанавливаем для объекта _x и _y на такие значения, чтобы расположить его внизу посередине экрана.

  3. Теперь нужно применить к объекту некоторое движение. Мы сделаем это с помощью управляющего элемента onEnterFrame, присвоенного фильму, следующим образом.
    currBullet_mc.onEnterFrame = bulletMove;
  4. Мы будем присваивать функцию и затем определять ее. Приведем функцию bulletMove.
    function bulletMove() {
        if (!this.shot) {
          this.xSpeed = (_root.cursor_mc._x-this._x)/20;
          this.ySpeed = (_root.cursor_mc._y-this._y)/20;
          this.shot = true;
        }
        this._x += this.xSpeed;
        this._y += this.ySpeed;
      }

    Она проверяет переменную с именем this.shot с использованием оператора "НЕ" -!. Это можно интерпретировать следующим образом: "если НЕ выстрел (если выстрел нулевой или не существует), то выполнить следующее:". Так как мы еще не определили shot, будет возвращаться значение true и блок кода будет выполняться. Будет вычисляться расстояние от пули до курсора, после чего оно будет делиться на 20, а результат будет использоваться для установки значений xSpeed и ySpeed. Далее this.shot устанавливается на значение "истина". Это предотвратит повторное выполнение данного блока кода. Затем значения xSpeed и ySpeed просто добавляются к значениям _x и _y пули.

  5. К данной функции нужно сделать еще одно дополнение, обеспечивающее удаления пули в случае, если она переместилась слишком далеко, что позволит избежать ненужных бесконечных вычислений позиции пули. Реализуется это так.
    if (this._y<0) }
        removeMovieClip(this);
      }

    Это действие будет выполняться сразу после установки параметра _y пули. Приведем код, который мы имеем на данный момент.

    Mouse.hide();
      cursor_mc.onEnterFrame = function() {
        this._x += _root._xmouse-this._x)/5;
        this._y += _root._ymouse-this._y)/5;
      };
      trigger = new Ob]ect();
      Key.addListener(trigger);
      trigger.onKeyDown = shoot;
      i = 0;
      function shoot() {
        currBullet_mc = _root.attachMovie("bullet", "bullet"+i, i);
        currBullet_mc._x = 275;
        currBullet_mc._y = 400;
        currBullet_mc.onEnterFrame = bulletMove;
        i++;
        if (i>9) {
          i = 0;
        }
      }
      function bulletMove() {
        if (!this.shot) {
          this.xSpeed = (_root.cursor_mc._x-this._x)/20;
          this.ySpeed = (_root.cursor_mc._y-this._y)/20;
          this.shot = true;
        }
        this._x += this.xSpeed;
        this._y += this.ySpeed;
        if (this._y<0) {
          removeMovieClip (this);
        }
      }
    Пример 6.1.

    До сих пор все, что было известно при нажатии клавиши - что какая-то клавиша была нажата, но неизвестно, какая именно. Например, у нас на экране могли бы находиться три отдельные пушки вместо одной. Мы уже говорили, что объект Key имеет параметры для хранения обозначения нажатой в данный момент клавиши, а также последней нажатой клавиши. Мы будем использовать второй параметр. У нас будет три пушки, управляемые клавишами z, x и с, что немного напоминает старую добрую игру 70-х годов "Missile Command". Мы можем получать данные двумя способами: в виде значения ASCII, или в виде кода клавиши. Значения ASCII привязаны к отдельным символам, а коды клавиш привязаны к отдельным клавишам клавиатуры. Например, заглавная буква "A" имеет код ASCII, равный 65, и код клавиши, также равный 65. В коде ASCII строчная буква "a" имеет значение 97. Но так как она является физически той же самой клавишей на клавиатуре, код клавиши по-прежнему равен 65. Имейте в виду, что в разных странах разные раскладки клавиатуры, и, следовательно, разные коды клавиш.

  6. Мы можем использовать широко распространенную таблицу кодов ASCII для выяснения значений z, x и c. Они равны, соответственно, 122, 120 и 99. Введем их в качестве констант в начале файла.
    FIRELEFT = 122;
      FIREMID = 120;
      FIRERIGHT = 99;
  7. Теперь мы используем выражение switch для проверки значения нажатой клавиши. Это новая возможность во Flash MX, которая имеется в большинстве других языков программирования. Проверяемое нами значение указывается в скобках после ключевого слова switch. После этого мы используем последовательность выражений типа "case", после которых указывается возможное значение с точкой с запятой. Если проверяемое значение соответствует данной величине, последующие выражения будут выполнены. В противном случае, будет осуществлен переход к следующему выражению case для проверки.

    Обратите внимание на слово break после каждого блока кода. Как только switch найдет удовлетворяющее значение, последует попытка выполнить весь последующий код, даже тот, который находится в другой секции case. Использование break заставляет Flash выйти из выражения switch и продолжить выполнение кода с данного места.

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

    function shoot() {
        keyPressed = Key.getAscii() ;
        switch(keyPressed){
          case FIRELEFT:
            startX = 50;
            break;
          case FIREMID:
            startx = 275;
            break;
          case FIRERIGHT:
            startX = 500;
            break;
          default:
            startX = 0;
      }
        if(startX){
          currBullet_mc = _root.attachMovie("bullet", "bullet"+i, i);
          currBullet_mc._x = startX;
          currBullet_mc._y = 400;
          currBullet_mc.onEnterFrarne = bulletMove;
          i++;
          if (i>9) {
            i = 0;
          }
        }
      }

    Здесь мы присваиваем значение ASCII нажатой клавиши переменной keyPressed. Затем мы используем switch для проверки ее на предопределенные значения FIRELEFT, FIREMID, FIRERIGHT. Если получаем совпадение, startX присваивается численное значение. Если совпадение не найдено (в случае, если нажата другая клавиша), startX присваивается значение 0.

    Если startX присвоено некоторое ненулевое значение, следует выстрел, как и ранее.

  8. Теперь у нас есть три функции и несколько дополнительных команд. Код стал несколько беспорядочным. Все эти дополнительные команды выполняются только один раз в начале фильма для его инициализации. Поэтому мы соберем их вместе и поместим в одну функцию с именем init.
    function init() {
        Mouse.hide();
        trigger = new Object();
        Key.addListener(trigger);
        trigger.onKeyDown = shoot;
        i = 0;
        FIRELEFT = 122;
        FIREMID = 120;
        FIRERIGHT = 99;
      }

    Теперь наш кадр состоит из четырех функций.

    init()
      cursor.onEnterFrame = function()
      shoot()
      bulletMove()
Игорь Хан
Игорь Хан

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

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

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

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

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