А с enterFrame надо разбираться дальше - слишком я уважаю концепцию событий.
Открываем для редактирования наш мувик и добавляем во FrameActions следущее:
1-й фрейм: gotoAndPlay(2)
2-й фрейм: gotoAndPlay(3)
3-й фрейм: gotoAndPlay(1)
Запускаем тест и ... повисаем.
Правда ненадолго - на 20 секунд. И окошко trace заполняется:
loadMC: _currentframe: 1
frame1: _currentframe: 1
frame2: _currentframe: 2
frame3: _currentframe: 3
frame1: _currentframe: 1
frame2: _currentframe: 2
frame3: _currentframe: 3
frame1: _currentframe: 1
frame2: _currentframe: 2
frame3: _currentframe: 3
frame1: _currentframe: 1
.......................
Точно - команда gotoAndPlay() срабатывание обработчика события enterFrame
НЕ ВЫЗЫВАЕТ, но самое приятное в этом тесте оказывается именно ПОВИСАНИЕ.
Честно-честно, я уже сталкивался с таким зависанием и уже знаю что это
означает. Означает это только одно, что команда gotoAndPlay несмотря на то,
выполняется после всех скриптов фрейма, цепочку команд при этом не разрывает,
а обеспечивает непосредственный переход к выполнению команд указанного фрейма.
Т.е. скрипты в разных фреймах выполняются как одним кускок без разрывов
для исполнения команд в других мувиках. Для кого-то последний абзац может
показаться либо тривиальным, либо сильно заумным, но это действительно ВАЖНО.
Во Flash реализована концепция многопоточного псевдопараллельного исполнения
процессов, где каждый процесс это мувик, точнее таймлайн. И если не понимать
КАК это реализовано, какие есть ограничения в этой реализации, можно угробить
любую, самую производительную машину. Что мы только что и сделали.
И еще один момент, требующий уточнения. Как видно из лога скрипты по команде
gotoAndPlay исполняются, а что происходит с изображением, графикой и т.п.
Для этого еще раз подредактируем мувик. В каждый кадр добавим по изображению
позволяющее четко идентифицировать кадр, например квадраты разного цвета.
И еще раз завесим машину.
Теперь четко видно, что хотя скрипты во всех вреймах исполняются, изображение
остается неизменным. Вот так - фрейм фрейму оказывается рознь. И если даже
покадрово анимация выполнена прекрасно, переходами с помощью gotoAndPlay
можно не только потерять несколько кадров, но и вообще всю анимацию.
И все таки остается вопрос когда же собственно срабатывает enterFrame.
Если заменить во FrameActions gotoAndPlay() на gotoAndStop() картинка
трассировки не изменяется (лог не привожу - придется поверить на слово)
А вот если в первом фрейме оставить gotoAndPlay(2), а во втором фрейме
совсем убрать gotoAnd... то картинка становится уже лучше. Напомню
что на событии enterFrame выполняется команда gotoAndPlay(this._currentframe - 1)
И получаем вот такой лог:
loadMC: _currentframe: 1
frame1: _currentframe: 1
frame2: _currentframe: 2
enterF: _currentframe: 2
afterG: _currentframe: 1
frame1: _currentframe: 1
frame2: _currentframe: 2
enterF: _currentframe: 2
afterG: _currentframe: 1
frame1: _currentframe: 1
frame2: _currentframe: 2
enterF: _currentframe: 2
afterG: _currentframe: 1
frame1: _currentframe: 1
........................
Четко видно по типу графики что отображается второй фрейм, а почти похож
на один из предыдущих вариантов, НО за маленьким исключением последовательность
выполнения FrameActions для кадра 2 и обработчика события для enterFrame
стала противоположной - а я все никак понять не мог почему в разной
документации относительно этого момента встречаются разночтения. Одни
утверждают, что сначала срабатывает обработчик событий, а затем скрипт
фрейма, другие, что все как раз наоборот. Оказывается, что все правы,
важны условия. Не знаю надо ли кому-то писать код так, чтобы от этой
последовательности зависел результат, но советую быть в этом случае
по-внимательней.
Но куда более существенный момент в том, что при этом тестировании выявилось
различие между тем что мы ВИДИМ и тем что на самом деле ПРОИСХОДИТ. Видим
мы только второй фрейм, а выполняются скрипты и первом и во втором. Если
бы не трассировка всех кадров мы могли обэтом даже не узнать.
Сдедовательно если организовывать паузу через
gotoAndPlay(this._currentframe - 1) в предыдущем фрейме не
должно быть никакого скрипта.
Что-то длинноватый текст получается, наверно уже и читателей не оталось
("редкая птица долетит до середины Днепра") будем заканчивать.
Последнее изменение - в обработчике события enterFrame вместо
всяких там gotoAnd... пишим грубо конкретное stop() и запускаем:
loadMC: _currentframe: 1
frame1: _currentframe: 1
frame2: _currentframe: 2
enterF: _currentframe: 2
afterG: _currentframe: 2
enterF: _currentframe: 2
afterG: _currentframe: 2
enterF: _currentframe: 2
afterG: _currentframe: 2
enterF: _currentframe: 2
afterG: _currentframe: 2
enterF: _currentframe: 2
afterG: _currentframe: 2
enterF: _currentframe: 2
afterG: _currentframe: 2
........................
Что и требовалось - фрейм всегда вторрой, обработчик живее всех живых
и способен делать что требуется, считать задержки, ожидать конкретных
событий, следить за значениями переменных и т.д.
Вобщем можно подводить итоги:
Как сделать: паузу см. код в самом начале.
Как сделать: реверс анимации используем gotoAndStop(this._currentframe - 1)
Как сделать: ускоренный реверс анимации - gotoAndStop(this._currentframe - 2)
Правда для чистого реверса FrameActions либо не должно быть совсем
либо они должны блокироваться флагом реверсирования.
Вот собственно и все - как этим материалов воспользоваться, решать вам
самим, "Кто предупрежден - тот вооружен", но если позволите я попробую
сформулировать некоторые размышления по этому поводу.
Прежде всего хочу отметить что данная граблеобразная "особенность" Flash
нигде в доступной мне документации полностью не описана. Может быть
это ноу-хау флэш-гуру.
Второе - нельзя абсолютно доверять значению переменной _currentFrame -
она изменяется после каждой команды gotoAnd...
Третье - последовательность исполнения FrameActions и обработчика
события enterFrame зависит от конкретной ситуации - т.е. каким
образом совершен переход на данный кадр.
Четвертое - событие enterFrame не срабатывает при переходе на фрейм
с помощью команды gotoAndPlay
И наконец, надо как-то честно предупредить начинающий флэшеров что во флеше
есть не только "конфетки" но и такого рода грабли.
Хотелось бы добавить в этакий кодекс молодого строителя флэш-коммунизма
следущее:
"Фрейм фрейму рознь"
"Стоп это плэй, а плэй это стоп"
"Верить никому нельзя, трэйсу можно ... самому полному трейсу"
и т.д.
Список предлагаю продолжить.
P.S. Все замечания к данному тексту прошу дублировать на
apm@tut.by
Best regards,
APM