Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 31.10.2013, 04:17
LIGHTHILL вне форума Посмотреть профиль Отправить личное сообщение для LIGHTHILL Найти все сообщения от LIGHTHILL
  № 1  
Ответить с цитированием
LIGHTHILL

Регистрация: Oct 2013
Сообщений: 5
По умолчанию Проблема с Event

Пытаюсь сделать анимацию клика. Создал сам MovieClip (расширяющийся кружочек из точки клика).
Сначала добавлял один экземпляр и в случае клика в другом месте, не закончившаяся анимация исчезала и воспроизводилась заново в новом месте. Всё работало. Решил сделать, что бы при каждом новом клике создавался новый экземпляр не мешая окончиться предыдущему. Но столкнулся с проблемой, в случае с одним экземпляром, переменная которого объявлялась ещё в самом классе, я без проблем обращался к номеру кадра этого экземпляра, и когда он оканчивался, я удалял его. Сейчас каждый новый экземпляр создаётся в функции ивента клика мышкой по сцене. И я не пойму как правильно написать Слушатель ON_ENTER_FRAME для каждого экземпляра. Всё время ошибки, и currentFrame всегда 1.
Вот то, что сделано на текущий момент (не работает):
Код AS3:
package 
{
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
 
	public class Main extends MovieClip 
	{
 
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
 
			stage.addEventListener(MouseEvent.CLICK, onClick);
		}
 
		private function onClick(e:MouseEvent): void
		{
			var circle:CircleAnimation = new CircleAnimation();
			stage.addChild(circle);
			circle.x = mouseX;
			circle.y = mouseY;
			circle.addEventListener(Event.ENTER_FRAME, onEnter);
			circle.addEventListener(Event.REMOVED_FROM_STAGE, onRemoved);
		}
 
		private function onEnter(e:Event): void
		{
			if (this.currentFrame == this.totalFrames)
			{
				stage.removeChild(this);
			}
		}
 
		private function onRemoved(e:Event): void
		{
			this.removeEventListener(Event.ENTER_FRAME, onEnter);
			this.removeEventListener(Event.REMOVED_FROM_STAGE, onRemoved);
		}
 
	}
 
}

Старый 31.10.2013, 14:44
samana вне форума Посмотреть профиль Отправить личное сообщение для samana Найти все сообщения от samana
  № 2  
Ответить с цитированием
samana
 
Аватар для samana

блогер
Регистрация: Mar 2008
Адрес: Днепропетровск
Сообщений: 1,783
Записей в блоге: 3
В методах onEnter и onRemoved, замените this на
Код AS3:
(e.currentTarget as MovieClip)
И не добавляйте объекты на stage. Вы ведь создаёте их в Main классе, вот в него и добавляйте.

Старый 31.10.2013, 14:54
Akopalipsis вне форума Посмотреть профиль Найти все сообщения от Akopalipsis
  № 3  
Ответить с цитированием
Akopalipsis
Banned
[+4 24.02.14]
[+4 07.11.13]
[+ 13.03.14]

Регистрация: Mar 2013
Сообщений: 1,864
samana давно подметил, что Вы очень хорошо знаете тему анимация, по этому задам Вам вопрос - в программе ( фп ) всегда работает EnterFrame и запись
Код AS3:
circle.addEventListener(Event.ENTER_FRAME, onEnter);
говорит о том, что circle мы заставляем слушать этот EnterFrame. Но правильно ли создавать для каждого обьекта свой обработчик ENTER_FRAME ? Лучше ведь когда создан класс с энтерФрайм и обьекты добавлять в него?

Старый 31.10.2013, 14:56
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 4  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
Но правильно ли создавать для каждого обьекта свой обработчик ENTER_FRAME ?
Не правильно. EnterFrame должен быть один на всю программу, в идеале. Чем больше таких слушателей, тем больше тормозов

Старый 31.10.2013, 14:59
samana вне форума Посмотреть профиль Отправить личное сообщение для samana Найти все сообщения от samana
  № 5  
Ответить с цитированием
samana
 
Аватар для samana

блогер
Регистрация: Mar 2008
Адрес: Днепропетровск
Сообщений: 1,783
Записей в блоге: 3
Да, лучше все объекты запихнуть в массив, и в одном энтерФрейме через цикл изменять в них свойства.
А лучше вообще сделать один энтерФрейм для всего приложения.
caseyryan опередил)

Старый 31.10.2013, 15:03
LIGHTHILL вне форума Посмотреть профиль Отправить личное сообщение для LIGHTHILL Найти все сообщения от LIGHTHILL
  № 6  
Ответить с цитированием
LIGHTHILL

Регистрация: Oct 2013
Сообщений: 5
Цитата:
Сообщение от samana Посмотреть сообщение
И не добавляйте объекты на stage. Вы ведь создаёте их в Main классе, вот в него и добавляйте.
Вот это не очень понял
Код AS3:
package 
{
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
 
	public class Main extends MovieClip 
	{
 
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
 
			stage.addEventListener(MouseEvent.CLICK, onClick);
		}
 
		private function onClick(e:MouseEvent): void
		{
			var circle:CircleAnimation = new CircleAnimation();
			addChild(circle);
			circle.x = mouseX;
			circle.y = mouseY;
			circle.addEventListener(Event.ENTER_FRAME, onEnter);
			circle.addEventListener(Event.REMOVED_FROM_STAGE, onRemoved);
		}
 
		private function onEnter(e:Event): void
		{
			if (e.target.currentFrame == e.target.totalFrames)
			{
				removeChild(MovieClip(e.target));
			} 
		}
 
		private function onRemoved(e:Event): void
		{
			e.target.removeEventListener(Event.ENTER_FRAME, onEnter);
			e.target.removeEventListener(Event.REMOVED_FROM_STAGE, onRemoved);
		}
 
	}
 
}
Вот так всё работает, в таком случае я куда добавляю объекты?

Старый 31.10.2013, 15:04
samana вне форума Посмотреть профиль Отправить личное сообщение для samana Найти все сообщения от samana
  № 7  
Ответить с цитированием
samana
 
Аватар для samana

блогер
Регистрация: Mar 2008
Адрес: Днепропетровск
Сообщений: 1,783
Записей в блоге: 3
Так вы добавляете в Main класс, всё верно.

Старый 31.10.2013, 15:11
Akopalipsis вне форума Посмотреть профиль Найти все сообщения от Akopalipsis
  № 8  
Ответить с цитированием
Akopalipsis
Banned
[+4 24.02.14]
[+4 07.11.13]
[+ 13.03.14]

Регистрация: Mar 2013
Сообщений: 1,864
caseyryan Спасибо! Тогда такой вопрос - подписывая circle на ENTER_FRAME, мы передаём listener в EventDispatcher, где он помещается в массив и при каждом тике, вызываются все listeners из массива. Если сделать отдельный класс для ENTER_FRAME, то в моём понимании, это будет выглядеть так - создали экземпляр и чтобы подписаться на его тики, мы передаем в него ссылку на класс с методом, который должен вызываться каждый тик. Передав ссылку в класс ENTER_FRAME, она помещается в массив и каждый тик, этот массив перебирается циклом и вызывает нужный метод. Получается тоже самое.
По этому мне кажется, что я не понимаю, как сделать один класс с ENTER_FRAME. Где я ошибаюсь?

Добавлено через 5 минут
Цитата:
Вот это не очень понял
Вы просто запомните, что так делать нельзя.
Код AS3:
stage.addChild(circle);
А вот так можно.
Код AS3:
this.addChild(circle);
Код AS3:
addChild(circle);

Старый 31.10.2013, 15:22
LIGHTHILL вне форума Посмотреть профиль Отправить личное сообщение для LIGHTHILL Найти все сообщения от LIGHTHILL
  № 9  
Ответить с цитированием
LIGHTHILL

Регистрация: Oct 2013
Сообщений: 5
И ещё вопрос, получается при каждом новом щелчке создаётся новый объект, как к этим объектам можно обратиться? Ведь их может быть бесконечно много. И как их можно сделать доступными для сборщика мусора, после удаления?

Добавлено через 10 минут
Сначала я сделал один экземпляр CircleAnimation в самом классе, всё отлично работало. Просто стало интересно как сделать так, что бы анимация не обрывалась при новом щелчке в другом месте. Может есть ещё какой-то менее ресурсозатратный способ?

Добавлено через 14 минут
А если я в самом классе CircleAnimation напишу, что бы он удалялся из родительского объекта после воспроизведения, будет лучше? Но, как я понимаю там опять же ENTER_FRAME нужно будет использовать.


Последний раз редактировалось LIGHTHILL; 31.10.2013 в 15:34.
Старый 31.10.2013, 15:38
samana вне форума Посмотреть профиль Отправить личное сообщение для samana Найти все сообщения от samana
  № 10  
Ответить с цитированием
samana
 
Аватар для samana

блогер
Регистрация: Mar 2008
Адрес: Днепропетровск
Сообщений: 1,783
Записей в блоге: 3
Цитата:
Сообщение от Akopalipsis Посмотреть сообщение
Тогда такой вопрос - подписывая circle на ENTER_FRAME, мы передаём listener в EventDispatcher, где он помещается в массив и при каждом тике, вызываются все listeners из массива. Если сделать отдельный класс для ENTER_FRAME, то в моём понимании, это будет выглядеть так - создали экземпляр и чтобы подписаться на его тики, мы передаем в него ссылку на класс с методом, который должен вызываться каждый тик. Передав ссылку в класс ENTER_FRAME, она помещается в массив и каждый тик, этот массив перебирается циклом и вызывает нужный метод. Получается тоже самое.
По этому мне кажется, что я не понимаю, как сделать один класс с ENTER_FRAME. Где я ошибаюсь?
Я не знаю, как там во флеше внутри реализована система передачи событий, но то, что одним энтерФрейм-ом быстрее перебрать в массиве все объекты, действительно лучше, чем на каждый объект вешать отдельный энетерФрейм.
Я сделал тест - подписал сто тысяч объектов, каждый на свой ентерФрейм, результат - 5 fps. А когда в цикле пробегал по этим ста тысячам - 16 fps.

Добавлено через 29 минут
LIGHTHILL Не забудьте, когда удаляете экземпляр CircleAnimation, остановить его внутренний енретФрейм. А то ещё некоторое время будет висеть в памяти, пока сборщик мусора не проснётся.
Код AS3:
circle.stop()

Создать новую тему Ответ Часовой пояс GMT +4, время: 02:14.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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