Регистрация: Sep 2001
Адрес: Минск, РБ
Сообщений: 106
|
Ахтунг - Грабли 2
Уважаемый All, я надеюсь, что предлагаемый материал поможет КАЖДОМУ
(т.е. не иолько новичкам) лучше ПОНИМАТЬ Flash и других флешеров.
Особенно если у него сложилось впечатление, что Flash это совсем
просто.
Часть 2
Реализованная во Flash концепция timelines и events при всей
внешней простоте и очевидности таит в себе ряд сюрпризов
натяжного и нажимного действия. Для тех кому это не сильно
интересно или не приходится реализовывать сложные переходы между фреймами
просто привожу код как можно реализовать паузу мувика несколько
отличный от канонического:
там где нужно организовать задержку 1c в каком-то мувике в любом месте пишем:
_level0.startPause = getTimer()
_level0.pauseDelay = 1000
Если нужно чтобы затормозился конкретный кадр (frameNum) то добавляем
gotoAndStop(frameNum)
а в самом мувике в его ObjectActions пишнм следующее
onClipEvent(enterFrame)
{ if (_level0.startPause != null)
{ if ((getTimer() - _level0.startPause) > _level0.pauseDelay)
{ startPause = null
this.play()
}
else
{ this.stop() }
}
}
Это работает, но вот обьяснить почему именно так, а не по другому,
к сожалению, очень кратко не получится.
Придется кое-что понять мягко говоря не совсем вытекающее из документации
от Macromedia, и честно говоря могущие постамить в тупик не только новичка
в програмировании. Попробую рассказать и проиллюстрировать с чем приходится
сталкиваться при организации сложных переходов по таймлайну.
Начнем как обычно: открываем Flash, создаем новый мувик с названием grabli2
и создаем новый символ типа мувиклип. В этом мувиклипе создаем три кейфрейма
и записываем в них следующие скрипты (соответственно)
1-й фрейм: trace("frame1: _currentframe: " + this._currentframe)
2-й фрейм: trace("frame2: _currentframe: " + this._currentframe)
3-й фрейм: trace("frame2: _currentframe: " + this._currentframe)
Графику в мувик добавлять вначале не надо может только отвлечь -
все самое интересное будет в окне trace.
Размещаем мувик на сцене и в его ObjectActions пишем:
onClipEvent(enterFrame)
{ trace("loadMC: _currentframe: " + this._currentframe)
}
onClipEvent(enterFrame)
{ trace("enterF: _currentframe: " + this._currentframe)
}
запускаем тестирование - в окне trace видим:
loadMC: _currentframe: 1
frame1: _currentframe: 1
enterF: _currentframe: 2
frame2: _currentframe: 2
enterF: _currentframe: 3
frame3: _currentframe: 3
enterF: _currentframe: 1
frame1: _currentframe: 1
enterF: _currentframe: 2
frame2: _currentframe: 2
enterF: _currentframe: 3
frame3: _currentframe: 3
enterF: _currentframe: 1
frame1: _currentframe: 1
.........
Все вроде как и должно быть, в каждом фрейме сначала исполняется код на событие
enterFrame, а затем код фрейма. В самом первом фрейме вместо события enterFrame
происходит событие load. Все в точном соответствии с докуменнтацией.
Обычно после такого эксперимента приобретаешь уверенность, что все понятно,
и чтобы рганизовать паузу достаточно дать команду
gotoAndPlay(myMovic._currentframe)
А вот так ли это сейчас и проверим - добавим в обработчик события enterFrame
сразу за сообщением trace команду gotoAndPlay(this._currentframe) и что
мы видим:
loadMC: _currentframe: 1
frame1: _currentframe: 1
enterF: _currentframe: 2
frame2: _currentframe: 2
enterF: _currentframe: 3
frame3: _currentframe: 3
enterF: _currentframe: 1
frame1: _currentframe: 1
enterF: _currentframe: 2
frame2: _currentframe: 2
enterF: _currentframe: 3
frame3: _currentframe: 3
enterF: _currentframe: 1
frame1: _currentframe: 1
....................
Нда, однако не получилось. И не понятно почему. Подозрение падает на команду
gotoAndPlay(this._currentframe) которая, почему-то не исполняется. До вчерашнего
дня я так и считал, что из текущего кадра просто нельзя сделать переход к нему
самому. Но все оказалось намного хуже. Нельзя то нельзя, но по такой причине,
что этот глюк показался совсем уж пустяковой мелочью.
Еще немного подправим обработчик события enterFrame следующим образом
onClipEvent(enterFrame)
{ trace("enterF: _currentframe: " + this._currentframe)
gotoAndPlay(this._currentframe - 1)
trace("afterG: _currentframe: " + this._currentframe)
}
т.е. раз не получилось перейти к текущему кадру, попробуем откатиться назад
(честно говоря я предполагал что после этого весь мувик будет прокручиваться
назад) и еще раз выведем переменную _currentFrame - хоть это и бессмысленно
на первый взгляд, но поверьте оно стоит того.
итак снова запускаем тест:
loadMC: _currentframe: 1
frame1: _currentframe: 1
enterF: _currentframe: 2
afterG: _currentframe: 1
frame2: _currentframe: 1
frame1: _currentframe: 1
enterF: _currentframe: 2
afterG: _currentframe: 1
frame2: _currentframe: 1
frame1: _currentframe: 1
enterF: _currentframe: 2
afterG: _currentframe: 1
frame2: _currentframe: 1
frame1: _currentframe: 1
enterF: _currentframe: 2
afterG: _currentframe: 1
frame2: _currentframe: 1
frame1: _currentframe: 1
........................
Ничего себе. Вам все понятно? А вот мне потребовалось приличный кусок
времени, чтобы осознать на какой "букет" удалось напороться.
Тем счаствливчикам которым все стало понятно с первого взгляда я искренне
завидую, а остальным предлагаю разобраться последовательно:
loadMC: _currentframe: 1 - ну это понятно - загрузка мувика
frame1: _currentframe: 1 - исполнение первого кадра после загрузки
enterF: _currentframe: 2 - тоже понятно - обработка события enterFrame
afterG: _currentframe: 1 - !СТОП. Не понял. _currentFrame изменился -
так какой же сейчас дествительно фрейм
после команды gotoAndPlay.
frame2: _currentframe: 1 - !!!ЧТО??? Фрейм остался прежний (второй)
а _currentFrame показывает какую-то чучу.
Нет наверное не чучу, а что-то что изменяется
командой gotoAndPlay. Странно как-то.
frame1: _currentframe: 1 - !!!СТОП. Фрейм сменился (куда заказывали) -
а ГДЕ!!! обработка события enterFrame?
enterF: _currentframe: 2 - А сейчас есть обработка.
afterG: _currentframe: 1
frame2: _currentframe: 1
frame1: _currentframe: 1 - А здесь снова нет!
enterF: _currentframe: 2
afterG: _currentframe: 1
frame2: _currentframe: 1
frame1: _currentframe: 1 - Может быть событие enterFrame не срабатывает
после команды gotoAndPlay
enterF: _currentframe: 2
afterG: _currentframe: 1
frame2: _currentframe: 1
frame1: _currentframe: 1 - ???
-----------------------------
Нннда, мало того что вместо паузы или прокрутки в обратном направлении
получили дергающийся мувик так еще и кучу сомнений зародили.
Самое серьезное сомнение в том насколько надежно срабатывает событие
enterFrame, второе - насколько можно доверять переменной _currentframe -
как-то мне приходилось видеть достаточно сложные алгоритмы анимации
в которых эта переменная активно используется. Как наверно приятно
обнаружить, что если слоем выше или даже просто чуть раньше выполнилась
команда gotoAnd... то изумительный алгоритм вычислит полную ахинею.
А вот еще код, автор которого безуспешно пытался понять, почему он не работает,
Есть кнопка, общая для всех кадров и на ней код
on(release)
{ if(_currentframe = 2)
{ gotoAndStop(5) }
if(_currentframe = 5)
{ gotoAndStop(2) }
..........
}
В пятом кадре она сработает, а вот во втором - фигу, и все вроде правильно.
Приятный сюрприз - грабли да и только.
Продолжение см. далее
|