|
|
|||||
Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
|
Таймер не останавливается
Друзья! Замутил простенькую анимацию заполнения шкалы. Метод update на входе получает новое значение отображаемого параметра, после чего выполняется:
public function update (value: Number) : void // Обновляет шкалу, по значению параметра { _newFilledHeigth = int(value / (_scaleMax-_scaleMin) * _heigth); _barTimer = new Timer(BAR_TIMER_INTERVAL); _barTimer.addEventListener(TimerEvent.TIMER, animatedFill); _barTimer.start(); } private function animatedFill(event:TimerEvent) : void { _currentFilledHeigth += _changeDirection * (BAR_ONE_TIME_STEP + BAR_STEP_INCREASE * event.target.currentCount); // Заполняем с ускорением if (Math.abs(_currentFilledHeigth-_newFilledHeigth) <= (BAR_ONE_TIME_STEP + BAR_STEP_INCREASE * event.target.currentCount)) // Если на следующей итерации достигли целевого значения { _currentFilledHeigth = _newFilledHeigth; redrawFilled(); // метод закраски кусочка до уровня _currentFilledHeigth _barTimer.stop(); _barTimer.removeEventListener(TimerEvent.TIMER, animatedFill); trace("закончили анимацию"); return; } else { redrawFilled(); trace("продолжили анимацию"); return; } } P.S. про твиннеры я в курсе, интересно самому разобраться.
__________________
Не сломано - не чини! |
|
|||||
Регистрация: Apr 2018
Сообщений: 42
|
Возможно ты устанавливаешь новый экземпляр таймера переменной _barTimer до того, как удаляется слушатель, либо снова его запускаешь. Вообще такое лучше делать через ENTER_FRAME, а не таймеры.
|
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Узким местом может быть создание каждый раз НОВОГО таймера при вызове апдейта. Соотв. приватная переменная перестает ссылаться на уже созданный и запущенный таймер, и отписки от него и остановки — не происходит. С таймерами всегда требуется повышенная осторожность)
__________________
Reality.getBounds(this); |
|
|||||
Зачем тебе вообще этот таймер? Используй лучше TweenMax или TweenLite. Просто при обновлении задаешь новое значение через TweenMax.to(...) и все грамотно анимируется. Только сразу в вызове update перед выполнением любого кода вызывай TweenMax.killTweensOf(твой объект);, чтобы не получилось так, что несколько твинов одновременно делают одно и тоже
__________________
Ко мне можно и нужно обращаться на ты) |
|
|||||
Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
|
Wolsh, твоя правда!
Перенёс объявление таймера в конструктор класса, а в методе update() записал _barTimer.reset() Всё стало работать правильно. Спасибо.
__________________
Не сломано - не чини! |
|
|||||
Регистрация: Apr 2018
Сообщений: 42
|
У тебя и в самом слушателе также косяк. Ты в рамках одного метода обращаешься к таймеру и через event.target и через поле _barTimer. И какой смысл в инструкциях return в конце каждого блока if else?
|
|
|||||
Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
|
RedHead90, ну не то чтобы косяк. Наверное да, не сама красивая запись, но как говорится, на скорость не влияет.
А с return вроде всё понятно. Ставишь после выполнения блока, чтобы дальше и не идти, врем не тратить
__________________
Не сломано - не чини! |
|
|||||
во-первых, вы используете динамический доступ - так теряется автокомплит и прочие компайл проверки, и да он не быстрый, хоть это и не критично
во-вторых, такой код явно указывает, что автор или не понимает свой код или не следит за его чистотой(и так сойдет) в-третьих, if(expr), который завершается return - не имеет смысла в else - он и так не выполнится зайдя в блок if, опять пеегруженность кода
__________________
местонахождение |
|
|||||
Регистрация: Apr 2018
Сообщений: 42
|
да-да. Ты же не ставишь для экономии времени в конце каждого метода return, а тут по факту делаешь тоже самое. А вообще действия, которые выполняются в любом случае, лучше вынести за пределы блока if else, чем дублировать их в каждом блоке, т.е. у тебя должен быть только if на проверку отписки от таймера, а метод redrawFilled() должен стоять перед этой проверкой, ведь он выполняется при любом раскладе. Плюс ты считаешь высоту сразу для двух итераций за раз, и одну из них прямо в условии проверки, что усложняет читаемость кода. В твоем случае достаточно просто проверить, достигло ли значение нужно величины. Код можно упростить
private function animatedFill(event:TimerEvent) : void { _currentFilledHeigth += _changeDirection * (BAR_ONE_TIME_STEP + BAR_STEP_INCREASE * _barTimer.currentCount); // Заполняем с ускорением _currentFilledHeigth = _currentFilledHeigth > _newFilledHeigth ? _newFilledHeigth : _currentFilledHeigth; redrawFilled(); if (_currentFilledHeigth == _newFilledHeigth) { _barTimer.stop(); _barTimer.removeEventListener(TimerEvent.TIMER, animatedFill); } } private function animatedFill(event:TimerEvent) : void { _currentFilledHeigth += _changeDirection * (BAR_ONE_TIME_STEP + BAR_STEP_INCREASE * _barTimer.currentCount); // Заполняем с ускорением if (_currentFilledHeigth >= _newFilledHeigth) { _currentFilledHeigth = _newFilledHeigth; _barTimer.stop(); _barTimer.removeEventListener(TimerEvent.TIMER, animatedFill); } redrawFilled(); } } |
|
|||||
Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
|
RedHead90, СлаваRa, ребята, большое спасибо за подробные разъяснения, всё намотал на ус. Да, действительно, когда изначально писал, вообще в событиях "плавал" по полной программе, только сейчас более-менее понимать начал механику.
Цитата:
__________________
Не сломано - не чини! |
Часовой пояс GMT +4, время: 18:08. |
|
« Предыдущая тема | Следующая тема » |
|
|