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

Движемся дальше

Более эффективное изменение размера

Намного проще иметь дело со статическими значениями, вычисляемыми только при изменении размера рабочего места. Это удобнее всего реализовать внутри самого объекта Stage, поэтому мы будем устанавливать параметры Stage.left, Stage.top, Stage.right и Stage.bottom каждый раз при изменении его размеров. Согласно словарю ActionScript, объект Stage имеет встроенный управляющий элемент, которому можно присваивать функцию. К сожалению, этот способ не работает, и единственный способ заставить его работать - это добавить объект Stage самому себе в качестве приемника (это подход может показаться странным, но он имеет положительный результат).

Итак, для функции Stage.onResize есть код (он приведен ниже), вызывающий каждую из четырех функций get и помещающий результаты в параметры внутри объекта Stage.

  1. Добавьте следующий код над функциями get.
    Stage.onResize = function() {
            this.left = this.getLeft();
            this.top = this.getTop();
            this.right = this.getRight();
            this.bottom = this.getBottom();
        };
  2. В процессе работы мы внесем значительные изменения в функцию get. Так как мы сначала вычисляем левую верхнюю позицию, мы можем приравнять правую позицию к левой плюс ширина и нижнюю к верхней плюс высота.
    Stage.getLeft = function() {
            return -1*(this.width-this.originalWidth)/2;
        };
        Stage.getTop = function() {
            return -1* (this.height-this.original-Height) /2;
        };
        Stage.getRight = function() {
            return this.left+this.width;
        };
        Stage.getBottom = function() {
            return this.top+this.height;
        };
  3. Затем добавляем приемник рабочего места.
    Stage.addListener(Stage);
        Stage.addListener(tl);
        Stage.addListener(tr);
        Stage.addListener(bl);
        Stage.addListener(br);

    Имейте в виду, что приемники принимают событие изменения размера в том порядке, в котором они добавлены, поэтому, в данном случае, Stage стоит на первом месте, затем идут tl, tr, bl и, наконец, br. Здесь это важно, так как нам нужно быть уверенными в том, что значения для левой, правой и т.д позиций, устанавливаются перед обращением к ним из фильмов.

  4. Теперь нам нужно пересоздать функции onResize фильма для использования новых значений.
    // top left
        tl.onResize = function() {
            this._x = Stage.left;
            this._y = Stage.top;
        };
        // top right
        tr.onResize = function() {
            this._x = Stage.right-this._width;
            this._y = Stage.top;
        };
        // bottom left
        bl.onResize = function() {
            this._x = Stage.left;
            this._y = Stage.bottom-this._height;
        };
        // bottom right
        br.onResize = function() {
            this._x = Stage.right-this._width;
            this._y = Stage.bottom-this._height;
        };
  5. Сохраните фильм в файле stageObject2.fla. Приведем полный код, функционирующий более "аккуратно".
    fscommand("allowscale", "false");
        Stage.scaleMode="showAll";
        Stage.originalWidth = Stage.Width;
        Stage.originalHeight = Stage.Height;
        Stage.scaleMode="noScale";
        Stage.onResize = function() {
            this.left = this.getLeft();
            this.top = this.getTop();
            this.right = this.getRight();
            this.bottom = this.getBottom();
        };
        Stage.getLeft = function() {
            return -1*(this.width-this.originalWidth) /2;
        };
        Stage.getTop = function() {
            return -1* (this.height-this.original-Height) /2;
        };
        Stage.getRight = function() {
            return this.left+this.width;
        };
        Stage. getBottom = function() {
            return this.top+this.height;
        };
        Stage.addListener(Stage);
        Stage.addListener(tl);
        Stage.addListener(tr);
        Stage.addListener(bl);
        Stage.addListener(br);
        // top left
        tl.onResize = function() {
            this._x = Stage.left;
            this._y = Stage.top;
        };
        // top right
        tr.onResize = function() {
            this._x = Stage.right-this._width;
            this._y = Stage.top;
        };
        // bottom left
        bl.onResize = function() {
            this._x = Stage.left;
            this._y = Stage.bottom-this._height;
        };
        // bottom right
        br.onResize = function() {
            this._x = Stage.right-this._width;
            this._y = Stage.bottom-this._height;
        };
    Пример 5.2.

Добавление движения при изменении размера рабочего места

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

  1. Добавьте следующий код над функциями onResize.
    MovieClip.prototype.slideTo = function(x, y, speed, callbackObj, callbackFunc) {
            var noo
            if (this.slideControl) {
                noo = this.slideControl;
            } else {
                noo = this.createEmptyMovieClip(<slideControl>,this.depth++);
            }
            noo.tx = x;
            noo.ty = y;
            noo.speed = speed;
            // store callback object / method (not used yet)
            noo.callBackObj = callBackObj;
            noo.callBackFunc = callBackFunc;
            noo.onEnterFrame = function() {
                this._parent._x += (this.tx-this._parent._x)/this.speed;
                this._parent._y += (this.ty-this._parent._y)/this.speed;
                if (Math.abs(this.tx-this._parent._x)<0.2 && Math.abs(this.ty
                Кthis._parent ._y) <0.2) {
                    this._parent._x = this.tx;
                    this._parent._y = this.ty;
                    // execute callback (we're not using this yet)
                    this.callBackObj [this.calIBackFunc](this._parent);
                    this.removeMovieClip();
                }
            };
        };
    Пример 5.3.
  2. Измените вызовы onResize, чтобы вызывать функцию slideTo со значениями X и Y в качестве конечных точек скольжения.
    tl.onResize = function() {
            var x = Stage.left;
            var у = Stage.top;
            this.slideTo(x, y, 5);
        }
        tr.onResize = function() {
            var x = Stage.right-this._width;
            var у = Stage.top;
            this.slideTo(x, y, 5);
        };
        bl.onResize = function() {
            var x = Stage.left;
            var у = Stage.bottom-this._height;
            this.slideTo(x, y, 5);
        };
        br.onResize = function() {
            var x = Stage.right-this ._width;
            var у = Stage.bottom-this._height;
            this.slideTo(x, y, 5);
        };
  3. Сохраните фильм в файле stageObject3.fla. При его запуске вы увидите, что углы постепенно появляются и скользят на свои позиции каждый раз при изменении размеров окна браузера или проигрывателя Flash. Приведем конечный код программы.
    fscommand("allowscale", "false");
        Stage.scaleMode="showAll";
        Stage.originalWidth = Stage.Width;
        Stage.originalHeight = Stage.Height;
        Stage.scaleMode="noScale";
        Stage.onResize = function() {
            this.left = this.getLeft();
            this.top = this.getTop();
            this.right = this.getRight();
            this.bottom = this.getBottom();
        };
        Stage.getLeft = function() {
            return -1*(this.width-this.originalWidth)/2;
        };
        Stage.get Top = function() {
            return -1*(this.height-this.originalHeight)/2;
        };
        Stage.getRight = function() {
            return this.left+this.width;
        };
        Stage.getBottom = function() {
            return this.top+this.height;
        };
        Stage.addListener(Stage);
        Stage.addListener(tl);
        Stage.addListener(tr);
        Stage.addListener(bl);
        Stage.addListener(br);
        MovieClip.prototype.slideTo = function(x, y, speed, callbackObj, callbackFunc) {
            var noo
            if (this.slideControl) {
                noo = this.slideControl;
            } else {
                noo = this.createEmptyMovieClip("slideControl",this.depth++);
            }
            noo.tx = x;
            noo.ty = y;
            noo.speed = speed;
            noo.callBackObj = callBackObj;
            noo.calIBackFunc = callBackFunc;
            noo.onEnterFrame = function() {
                this._parent._x += (this.tx-this._parent._x)/this.speed;
                this._parent._y += (this.ty-this._parent._y)/this.speed;
                if (Math.abs(this.tx-this._parent._x)<0.2 &&Math.abs(this.ty
                Кthis._parent._y)<0.2) {
                    this._parent._x = this.tx;
                    this._parent._y = this.ty;
                    this.calIBackObj [this.calIBackFunc](this._parent);
                    this.removeMovieClip();
                }
            };
        };
        tl.onResize = function() {
            var x = Stage.left;
            var у = Stage.top;
            this.slideTo(x, y, 5);
        };
        tr.onResize = function() {
            var x = Stage.right-this._width;
            var у = Stage.top;
            this.slideTo(x, y, 5);
        };
        bl.onResize = function() {
            var x = Stage.left;
            var у = Stage.bottom-this._height;
            this.slideTo(x, y, 5);
        };
        br.onResize = function() {
            var x = Stage.right-this._width;
            var у = Stage.bottom-this._height;
            this.slideTo(x, y, 5);
        };
    Пример 5.4.

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

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

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

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

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

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

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