Anthill Game Framework

Tiny framework for creating Flash games.

Инструменты пользователя

Инструменты сайта


guide:bubble_events

Всплывающие события

:!: :!: :!: С версии Anthill 0.3.5 добавлен новый механизм для перехвата и обработки всплывающих сообщений, в связи с этим данный материал является устаревшим и требует обновления. Будьте внимательны.

С версии Anthill 0.3.1 добавлена возможность работы со всплывающими событиями — такая модель событий позволяет подписываться не на конкретные события для конкретных объектов, а, например, на целый игровой мир сразу.

Использовать всплывающие события можно в любых классах, которые реализуют интерфейс ru.antkarlov.anthill.events.IBubbleEventHandler. С версии 0.3.1 по умолчанию этот интерфейс имплементирует AntEntity — это означает, что все основные объекты могут перехватывать и генерировать всплывающие события.


Отправка всплывающего события

Предположим, что вам необходимо обрабатывать какие-то события, которые могут производить разные объекты. Чтобы не подписываться на каждый такой объект, можно подписаться на весь игровой мир или на сущность, которая содержит такие объекты и обрабатывать их по мере поступления.

Первым делом напишем простой класс, который будет унаследован от AntEntity, а его основной задачей будет являться генерация всплывающих событий с заданным интервалом.

Объявляем приватные переменные:

private var _hitSignal:AntDeluxeSignal;
private var _hitInterval:Number;

Первая переменная — это наше событие (сигнал), которое будет отправлять данные. А вторая переменная это простое значение-задержка между отправкой сообщений.

Теперь рассмотрим конструктор класса:

public function TestUnitEvent()
{
  _hitSignal = new AntDeluxeSignal(this, AntEvent);
  _hitInterval = 2;
}

Особое внимание тут следует обратить только на строку инициализации самого дэлюксового сигнала. При создании экземпляра дэлюкс сигнала первым делом обязательно необходимо указать объект, который будет производить этот самый сигнал — тут практически всегда следует указывать класс, владеющий данным сигналом, то есть this. Остальными аргументами через запятую или массивом мы указываем типы аргументов, которые будут переданы в сигнал при его вызове — это нужно для строгой типизации так же как и в обычном AntSignal.

Теперь перекроем метод update() и реализуем отправку сообщения:

override public function update():void
{
  _hitInterval -= 2 * AntG.elapsed;
  if (_hitInterval <= 0)
  {
    // Вызываем сигнал и в качестве аргумента создаем событие — если событие не создать,
    // то сигнал не будет всплывающим. Агрумент true также обозначает, что событие всплывающие.
    _hitSignal.dispatch(new AntEvent(true));
 
    _hitInterval = 2; // Задержка до следующего вызова сигнала.
  }
}

Обратите внимание на то, что при вызове сигнала необходимо в качестве аргумента создать или передать уже существующее событие AntEvent. Если событие не передать, то сигнал не «всплывет».

Передаваемое событие — это объект, который будет нести в себе информацию, поднимаясь по иерархии приложения. Флаг true при создании события также является важным атрибутом, определяющим, является ли созданное событие всплывающим.


Обработка всплывающих событий

Чтобы перехватить и обработать всплывающее событие, достаточно перекрыть родительский метод onEventBubbled(aEvent:IEvent), если ваш класс унаследован от AntEntity и его потомков, или реализовать данный метод в соответствии с интерфейсом IBubbleEventHandler.

override public function onEventBubbled(aEvent:IEvent):Boolean
{
  // Тут можно обработать полученное событие.
  trace("Catcher::onEventBubbled()");
 
  // Если вернуть false, дальнейшая рассылка события будет прекращена
  return true;
}

В данном методе можно перехватить и обработать полученное сообщение. Также этот метод должен вернуть true или false. Если метод возвращает false, то дальнейшая рассылка сообщения прекращается.

Теперь давайте рассмотрим общую структуру возможного приложения, чтобы понять как все описанное выше, можно связать воедино:

// Создаем и добавляем в структуру экземпляр перехватчика
var catcher:MyEventCatcher = new catcher:MyEventCatcher();
add(catcher);
 
// Создаем и добавляем посредников
var en1:AntEntity = new AntEntity();
// Новую группу вкладываем в группу перехватчика
catcher.add(en1); 
 
var en2:AntEntity = new AntEntity();
// Очередную группу вкладываем в предыдущую группу
en1.add(en2);
 
// Создаем объект, который будет генерировать события
var pulsar:PulsarEvent = new PulsarEvent();
// Вкладываем генератор событий в последюю группу
en2.add(pulsar);

Таким образом мы получили что-то вроде древовидной структуры с одной ветвью. Листом данной ветви выступает объект, генерирующий события-пустышки с заданным интервалом, а основой этой ветви является объект, который при получении события будет выводить сообщение в окно output. Если эту структуру запустить в работу, то через определенный промежуток времени catcher будет выводить в окно output текстовую строку при каждом получении всплывающего события.


Передача полезной информации

Чтобы из рассмотренной выше спам-машины, забивающей окно output бесполезными сообщениями, сделать что-то более полезное, необходимо передавать и использовать какую-либо информацию.

Всплывающий AntEvent (IEvent) по умолчанию имеет следующие параметры:

  • target:Object — Указатель на объект, который произвел событие;
  • currentTarget:Object — Указатель на текущий объект-посредник, который передал событие;
  • signal:AntDeluxeSignal — Указатель на сигнал, который породил событие.

Помимо этого, при создании AntEvent вторым аргументом можно задать любой пользовательский объект, который можно извлечь в методе обработчике:

// Передаем полезные значения
_hitEvent.dispatch(new AntEvent(true, { someValue:"Hello!" });

А в методе обработчике извлекаем переданные значения:

override public function onEventBubbled(aEvent:IEvent):Boolean
{
  var e:AntEvent = aEvent as AntEvent;
  if (e != null && e.userData != null)
  {
    trace(e.userData.someValue);
  }
 
  return true;
}

Поскольку AntDeluxeSignal работает с событиями, реализующими интерфейс IEvent, вы можете создавать свои классы событий с более широкими и интересными возможностями.

Внимание: При реализации своей структуры со всплывающими событиями ваши объекты должны иметь параметр parent, который должен указывать на родительский объект, чтобы была возможность передать событие выше по иерархии. Если параметра parent нет или он равен null, сообщение прекратит свой процесс всплывания.


guide/bubble_events.txt · Последние изменения: 11.05.2014 23:11 — Anton Karlov