Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Возникло недопонимание интервальных функций (http://www.flasher.ru/forum/showthread.php?t=112519)

orcpochta 30.05.2008 13:07

Возникло недопонимание интервальных функций
 
Пример-программа из библии по AS2.0, где генерируются мерцающие буквы в случайном месте сцены. В среде авторских работ создается динамическое текстовое поле, куда монтируется несколько букв определенного шрифта для дальнейшего программного доступа к ним.
Далее пишется следующий код:
Код:

function displayLetter():Void {

  // Create a random integer to yield one of the indices from the
  // aLetters array.
  var nRandomIndex:Number = Math.ceil(Math.random() * aLetters.length) - 1;

  // Create random numbers to use for the x and y coordinates of the
  // letter TextField.
  var nRandomX:Number = Math.random() * 550;
  var nRandomY:Number = Math.random() * 400;

  // Get the next available depth;
  var nDepth:Number = this.getNextHighestDepth();

  // Create a new TextField object at the random x and y coordinates.
  this.createTextField("tLetter" + nDepth, nDepth, nRandomX, nRandomY, 0, 0);

  // Assign a reference to a variable to make it more convenient to
  // work with the TextField.
  var tLetter:TextField = this["tLetter" + nDepth];

  // Set the autoSize and text properties so the random letter
  // displays.
  tLetter.autoSize = "left";
  tLetter.text = aLetters[nRandomIndex];

  // Set a custom property called fadeDirection that determines
  // the increment by which the alpha will change. And set the
  // alpha to 0 initially.
  tLetter.fadeDirection = 5;
  tLetter._alpha = 0;

  // Tell Flash to embed the font for the TextField.
  tLetter.embedFonts = true;

  // Create a TextFormat object that tells Flash to use the
  // Verdana font and set the size to 15.
  var tfFormatter:TextFormat = new TextFormat();
  tfFormatter.font = "Verdana";
  tfFormatter.size = 15;

  // Assign the TextFormat to the TextField.
  tLetter.setTextFormat(tfFormatter);

  // Set an interval at which the letter will fade in and out.
  tLetter.nInterval = setInterval(this, "alphaFade", 10, tLetter);
}

function alphaFade(tLetter:TextField):Void {

  // Increment the letter TextField's alpha.
  tLetter._alpha += tLetter.fadeDirection;

  // Check to see if the letter has faded in completely. If so
  // set the fadeDirection property to -5 so that the TextField
  // starts to fade out. Otherwise, if the letter has faded out
  // completely...
  if(tLetter.fadeDirection > 0 && tLetter._alpha >= 100) {
    tLetter.fadeDirection = -5;
  }
  else if(tLetter.fadeDirection < 0 && tLetter._alpha <= 0) {
    // ... clear the interval and remove the TextField.
    clearInterval(tLetter.nInterval);
    tLetter.removeTextField();
  }

  // Make sure to update the screen.
  updateAfterEvent();
}

// Create the array of letters.
var aLetters:Array = ["a", "b", "c", "d", "e", "f"];

// Set the interval at which a new letter should be displayed.
var nDisplayInterval:Number = setInterval(this, "displayLetter", 1);

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

var nDepth:Number = this.getNextHighestDepth();
trace(nDepth);

- выдает undefined.
Стал искать серьезные отличии в кодах и увидел, что у меня запуск интервальных функций инициализирован не
Код:

tLetter.nInterval = setInterval(this, "alphaFade", 10, tLetter);
var nDisplayInterval:Number = setInterval(this, "displayLetter", 1);

, а
Код:

tLetter.nInterval = setInterval(alphaFade, 10, tLetter);
var nDisplayInterval:Number = setInterval(displayLetter, 1);

- к чему я, собственно, изучая эту книгу и привык.
Т.е. в книге говорится, что синтаксис запуска функций: setInterval(functionName, interval, params );
объектных методов: setInterval(objectName, "objectMethod", interval, params);

Посмотрел мануал, действительно, есть синтаксис setInterval(this, "functionName", interval, params); - я так понимаю, что он идентичен синтаксису setInterval(functionName, interval, params );, но почему же тогда при синтаксисе через this все работает, а при другом нет?
Объясните разницу, если она есть, плиз.

Извините, что так много букв...)))

Волгоградец 30.05.2008 13:36

Все упирается в область видимости имен. Если в функции displayLetter () есть ссылка с помощью this, то в методе setInterval () эта ссылка даст другое значение. Когда используешь такую сигнатуру:
Код:

setInterval(objectName, "objectMethod", interval, params);
То сам задаешь область видимости функции.

orcpochta 30.05.2008 13:58

Извините, ничего не понял..((

Волгоградец 30.05.2008 14:25

http://www.flasher.ru/forum/showthread.php?t=104635

Alex_beginner 30.05.2008 14:55

Если Вы проанализируете работу вот этого кода то поймете почему.
Код:

myObject:Object = {};
myObject.method = function(par:String):Void
    {
        trace(par);
    };
setInterval(myObject, "method", 100, "Привет orcpochta");


orcpochta 30.05.2008 15:02

я примерно понял, но осталось уяснить какую роль играет this в самом первом вызове интервальной функции var nDisplayInterval:Number = setInterval(this, "displayLetter", 1); - чем this там является?

Цитата:

Сообщение от Alex_beginner (Сообщение 742677)
Если Вы проанализируете работу вот этого кода то поймете почему.
Код:

myObject:Object = {};
myObject.method = function(par:String):Void
    {
        trace(par);
    };
setInterval(myObject, "method", 100, "Привет orcpochta");


забыли var в объявлении myObject..))
опять же тут все ясно: создается объект, ему присваивается метод, который затем и вызывается в интервале - но это никак меня не приблизило к пониманию моего вопроса..))

Alex_beginner 30.05.2008 15:15

Код:

забыли var в объявлении myObject..))
Виноват, исправляюсь! Сильно торопился Вам помочь, что даже ненаписал var.:)

Волгоградец 30.05.2008 15:45

Если здесь
Код:

var nDisplayInterval:Number = setInterval(this, "displayLetter", 1);
опустить слово this, то получится вот что:
вот эта строчка
Код:

this.createTextField("tLetter" + nDepth, nDepth, nRandomX, nRandomY, 0, 0);
не будет работать, т.к. в этом случае слово this будет относиться к методу setInterval (), т.е. для компилятора строчка будет выглядеть как
Код:

setInterval.createTextField()
А т.к. у setInterval нет такого метода, то и появляется ошибка.

orcpochta 01.06.2008 17:18

Спасибо! Разобрался..))

etc 09.06.2008 15:25

Цитата:

Сообщение от Волгоградец (Сообщение 742701)
Если здесь
Код:

var nDisplayInterval:Number = setInterval(this, "displayLetter", 1);
опустить слово this, то получится вот что:
вот эта строчка
Код:

this.createTextField("tLetter" + nDepth, nDepth, nRandomX, nRandomY, 0, 0);
не будет работать, т.к. в этом случае слово this будет относиться к методу setInterval (), т.е. для компилятора строчка будет выглядеть как
Код:

setInterval.createTextField()
А т.к. у setInterval нет такого метода, то и появляется ошибка.

Неправда.

Волгоградец 09.06.2008 16:32

Как неправда???! Просветите, пожалуйста.

etc 09.06.2008 16:37

Цитата:

Сообщение от Волгоградец (Сообщение 744687)
Как неправда???! Просветите, пожалуйста.

Узнайте, что такое «область видимости».

Волгоградец 09.06.2008 16:55

__etc, при всем моем уважении, но помощь у вас неважная.
Цитата:

Цепочка областей видимости — это список ActionScript-объектов. Flash Player ищет идентификатор, начиная с последнего элемента в цепочке областей видимости, и продолжает подниматься по цепочке, пока не найдет его.
В случае с setinterval () this в качестве первого параметра - это объект _root, при условии что код находится на главной временной диаграмме?

etc 09.06.2008 16:59

this — это ссылка на самого себя. При передачи области видимости метод будет выполнен в ней. Если область не указана, то метод будет выполнен в анонимной области видимости.

p.S. В помошники я и не записывался.

Волгоградец 09.06.2008 17:18

Предполагаю, что анонимная область видимости - это объект Object или _root, другими словами.

etc 09.06.2008 17:35

Нет, у этой области видимости вообще нет this, это не _root и не Object.

Волгоградец 09.06.2008 17:53

__etc, если не секрет, откуда вы это узнали - этого нет ни в хэлпе, ни в других букварях и даже Гугле!!! Я вот впервые услышал про анонимную область видимости и до сих пор не понимаю ее смысл.

wvxvw 09.06.2008 18:31

в этом можно легко убедиться =)
Код:

setTimeout.someVar = 'foo';
var i:Number = setTimeout(someFunc, 100);
function someFunc():Void {
        trace(this); //undefined
        trace(this.someVar); //undefined // this не указывает на setTimeout
        trace(arguments.callee.someVar); //bar // arguments.callee указывает на someFunc
        trace(arguments.caller.someVar); //undefined // arguments.caller не указывает на setTimeout
}
someFunc.someVar = 'bar';


Волгоградец 10.06.2008 10:19

Я в замешательстве... Почему вот так вообще не выполняется код:
Код:

var i:Number = setTimeout(this, someFunc, 100);
В данном случае this ссылается на объект, который активировал код. Согласно цепочке областей видимости компилятор ищет этот объект вне функции - получается, в setTimeout(). Там не находит и поднимается выше - а это уже _root. Почему же тогда ничего не выполняется?

etc 10.06.2008 10:32

Надо передавать название метода в объекте, а не ссылку на этот метод.

Волгоградец 10.06.2008 10:46

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

iNils 10.06.2008 13:15

__etc говорил об втором аргументе, это не ссылка на функцию, а строка.

Волгоградец 10.06.2008 13:41

Точно! Невнимательность, блин. Спасибо всем.

Волгоградец 10.06.2008 20:31

Разрешите еще вопрос. Почему вот это не работает?
Код:

var mc1:MovieClip = this.attachMovie ("mc1", "mc1", 1, {_x: 20, _y: 200});
var mc2:MovieClip = this.attachMovie ("mc2", "mc2", 2, {_x: 200, _y: 200});
var i:Number = setTimeout(mc2, "moving", 100);
function moving ():Void{
  this._x += 100;
  trace (this);
}

Я вроде вызываю функцию из области видимости mc2, следовательно this должен сослться на mc2, но ничего не выводится, даже трейс не дает ничего.

wvxvw 10.06.2008 20:46

Ну, как бы у mc2 нет такого метода... вот ничего и не вызывается, это ж не Delegate %)
Код:

import mx.utils.Delegate;
//
var mc1:MovieClip = this.attachMovie ("mc1", "mc1", 1, {_x: 20, _y: 200});
var mc2:MovieClip = this.attachMovie ("mc1", "mc2", 2, {_x: 200, _y: 200});

function moving ():Void{
  this._x += 100;
  trace (this);
}

var movingDelegate:Function = Delegate.create(mc2, moving);
// or:
// var movingDelegate:Function = new Delegate(moving).createDelegate(mc2);
var i:Number = setTimeout(movingDelegate, 100);


Волгоградец 10.06.2008 22:55

Спасибо, Олег. Вроде разобрался.


Часовой пояс GMT +4, время: 21:19.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.