Опубликован: 07.11.2006 | Доступ: свободный | Студентов: 3401 / 339 | Оценка: 3.94 / 3.71 | Длительность: 37:11:00
Лекция 4:

Рисование API

  1. Мы закончили создание фильма. Теперь перетащите его на рабочее место и назовите инстанс listingsPanel.

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

    function drawPanel() {
      // turn off the back button and the save button
      backButton._visible = false;
      saverButton._visible = false;
      // make the menu panel visible
      this.listingsPanel._visible = true;
      // retrieve the shared object
      myPictureObj = SharedObject.getLocal("pictures");
      // list any drawings
      listDrawings(myPictureObj.data.arrays);
      // check if we need to turn on the scrollers
      initScrollers();
    }

    Здесь мы инициализировали общий объект и сохранили его в myPictureObj, а также настроили отображение некоторых элементов рабочего места. Далее мы вызовем listDrawings для просмотра myPictureObj и выяснения количества находящихся там рисунков. Мы запишем наши массивы точек в массив с именем arrays объекта sharedObject и затем передадим этот массив функции listDrawings. Внутри массива arrays будет находиться один массив для каждого рисунка. Вместо создания кнопки для каждого рисунка мы используем функцию asfunction, позволяющую представлять фрагмент текста HTML в виде ссылки на функцию ActionScript. Вот как это делается.

    asfunction:functionName, parameter;
  2. Мы будем использовать эту функцию для вызова _root.redraw и передачи номера записи массива.
    function listDrawings(pictureArray) {
      listingsPanel.lista.htmlText = "";
      // loop through the picture array
      for (var i = 0; i<pictureArray.length; i++) {
      // for each entry in the picture array add another line
      // to the text in the textfield
      var nexta = "<A HREF='asfunction:_root.redraw,"+i+"'>"+"
       Drawing Number "+(i+1)+"</A><b/>";
      listingsPanel.lista.htmlText += nexta;
      }
    }
  3. Теперь создадим вторую функцию, которая будет вызываться drawPanel. Она просто настроит отображение кнопок прокрутки в зависимости от того, где мы находимся - вверху или внизу текстового поля, а также от того, может ли поле вместить все содержащиеся в нем строки текста. С помощью with мы перейдем внутрь фильма listingsPanel. Параметр visible инстанса кнопки downScroll устанавливаем на значение on, если значение прокрутки меньше, чем максимально возможное значение прокрутки. Этот же параметр устанавливается на значение on, если текстовое поле было полностью прокручено.
    function initScrollers() {
      with (this.listingsPanel) {
        downScroll._visible = lista.scroll<lista.maxscroll;
        upScroll._visible = lista.scroll>l;
      }
    }

    Наш список будет выглядеть примерно так.


  4. Теперь добавим уже знакомые вам функции для рисования. Сначала добавим initDraw - функцию, которая будет вызываться при щелчке пользователя на кнопке new:
    function initDraw() {
      // turn on the back and save buttons
      backButton._visible = true;
      saverButton._visible = true;
      // turn off the menu
      _root.listingsPanel._visible = false;
      // create an array for the points
      tempArr = [];
      _root.lineStyle(1, 0x000000);
      // set up out mouse event handlers
      _root.onMouseDown = drawOn;
      _root.onMouseUp = drawOff;
    }

    Все это вам уже знакомо: сначала настраивается отображение элементов рабочего места так, чтобы были видны кнопки back и save, затем настраивается lineStyle и создается массив для наших точек.

    function drawOn() {
      this.moveTo(this._xmouse, this._ymouse);
      tempArr.push({x:this._xmouse, y:this._ymouse});
      this.onMouseMove = addPoint;
    }
    function addPoint() {
      tempArr.push({x:this._xmouse, y:this._ymouse});
      this.lineTo(this._xmouse, this._ymouse);
    }
    function drawOff() {
      tempArr.push("break");
      delete this.onMouseMove;
    }
  5. Затем создадим функцию, позволяющую сохранять рисунок. Она будет вызываться при нажатии кнопки save и будет сохранять tempArr в общем объекте. Перед сохранением массива мы удаляем последний объект, так как объект точки записывается в массив, когда пользователь нажимает кнопку для ее сохранения (когда происходит onMouseDown ). Если не делать этого, можно столкнуться с проблемами потерянной строки в конце рисунка.
    function save() {
      // remove final element
      tempArr.pop();
      if (!myPictureObj.data.arrays) {
      // if our array for pictures has not yet been created,
      // create it
      myPictureObj.data.arrays = [];
      }
      // put the current picture array into the array
      // containing all pictures
      myPictureObj.data.arrays.push(tempArr);
      // update the shared object
      myPictureObj.flush();
      // return to the menu screen
      _root.backToMain();
    }

    Обратите внимание, что здесь сначала проверяется существование массива arrays, и если массив не существует, то он создается. Затем tempArr помещается в конец этого массива и вызывается flush для сохранения его в объекте. После этого вызывается backToMain для удаления всех управляющих элементов событий, а также весь рисунок в фильме, перед возвращением к началу.

    function backToMain() {
      delete _root.onEnterFrame;
      delete _root.onMouseMove;
      delete _root.onMouseDown;
      delete _root.onMouseUp;
      _root.clear();
      _root.drawPanel();
    }
  6. Теперь приступим к созданию последней части - функции перерисовки. Здесь нам нужны две функции: redraw для начала перерисовки и drawNextPoint для покадрового продолжения. Перерисовка осуществляется посредством прохода через массив точек и рисования линии от предыдущей точки к текущей в каждом кадре. С помощью break осуществляется переход к точке без рисования линии.
    function redraw(num) {
      backButton._visible = true;
      this.listingsPanel._visible = false;
      // set count to zero, used to keep track of current point
      this.count = 0;
      // the array which we are redrawing
      this.currentArr = myPictureObj.data.arrays[num];
      this.lineStyle (0x000000);
      this.moveTo( this, currentArr [0] .x, this .currentArr [0] .y);
      // every frame we draw the next point
      this.onEnterFrame = drawNextPoint;
    }
  7. Это начальная функция, получающая массив нужного рисунка и перемещающая точку рисования на первую позицию в массиве. Она сбрасывает переменную count, которая будет использоваться для учета точки выхода из массива, и затем настраивает функцию enterFrame на drawNextPoint.
    function drawNextPoint() {
      this.count++;
      // nextEntry is the next point object in the array
      var nextEntry = this.currentArr[this.count];
      if (nextEntry != "break") {
        this.lineTo(nextEntry.x, nextEntry.y);
      } else {
        // if the nextEntry is "break", we increment count
        // and move to the next point.
        this.count++;
        var nextEntry = this.currentArr[this.count];
        this.moveTo(nextEntry.x, nextEntry.y);
      }
      if (this.count>this.currentArr.length) {
        // we have drawn all available points
        delete this.onEnterFrame;
      }
    }

    Таким образом, с помощью drawNextPoint мы увеличиваем значение нашего счетчика и устанавливаем переменную nextEntry для указания на следующую запись в массиве. Мы проверяем, равно ли это значение "break" и, если это так, увеличиваем count и переходим к следующей точке в массиве с помощью moveTo. Если оно не равно "break", рисуем линию к новой точке. Наконец, проверяем, достигнут ли конец массива; если да, удаляем функцию onEnterFrame и завершаем выполнение действия.

  8. Последняя - это функция инициализации, которая будет просто устанавливать управляющие элементы для кнопок, настраивать textField в listingsPanel на HTML-текст и рисовать панель в первый раз.
    function init() {
      this.saverButton.onPress = this.save;
      this.backButton.onPress = this.backToMain;
      with (this.listingsPanel) {
        newButton.onRelease = this.initDraw;
        // enable html text in the textfield
        lista.html = true;
        downScroll.onPress = function() {
          // scroll the textfield down
          lista.scroll++;
          // check if the scrollers should still appear
          _root.initScrollers();
        };
        upScroll.onPress = function() {
          lista.scroll--;
          _root.initScrollers();
        };
      }
      drawPanel();
    }
  9. Нам также нужен вызов этой функции для инициализации приложения
    init ()

Весь код программы находится в файле drawingapp.fla.

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

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

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

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

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

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