Nape 2 — Некоторые нюансы обработки взаимодействий

Эта статья как небольшое дополнение к предыдущей и рассказывает некоторых нюансах.

Хочу начать с события ONGOING.
Как было сказано в предыдущей статье это событие генерируется когда тела столкнулись и продолжают сталкиваться (кубик упал на платформу и лежит на ней).
Возьмем этот же пример с кубиком, который упал и лежит. Если подключить слушатели для BEGIN и ONGOING, а в обработчиках этих событий выводить трейсы - trace(«BEGIN») и trace(«ONGOING») соответственно, то вы получите такую картину (я вывожу слово «step», чтобы обозначить на каком шаге симуляции происходит событие):
«step 1″
«BEGIN»
«ONGOING»

«step 2″
«ONGOING»

«step 3″
«ONGOING»
……
Я считаю что это не совсем корректно, но именно так происходит.
Почему не совсем корректно? Событие ONGOING говорит о том, что тело продолжает сталкиваться (не при первом касании, а именно при продолжении этого касания), а тут что происходит? Даже при первом касании сразу вызывается и BEGIN и ONGOING, хотя по идее должен был вызваться только BEGIN. По крайней мере хорошо, что хотя бы BEGIN вызывается первым :)
Это небольшая особенность но ее надо иметь ввиду. Напр., вы захотели сделать какой то эффект когда тело скользит по полу (именно скользит, а не отскакивает). Тогда вы бы захотели использовать событие ONGOING для этого. Вот именно в этом случае вы должны знать этот нюанс.

 

Далее поговорим о свойстве cbType
В прошлой статье я не случайно сделал акцент на том, что свойство cbType присутствует у класса Interactor как базового класса для Shape, Body, Compound.
Это значит что вы можете отслеживать не только тела, а и столкновение конкретных шейпов до столкновения сложных тел (Compound). Мало того, возможно также отслеживать любые комбинации между этими тремя типами. Напр., вы даже можете отследить столкновение конкретного шейпа со сложным телом (Shape-Compound).

Еще одно свойство (маленькое но важное я считаю), которого не было в предыдущей версии.
Обратите внимание на то что когда создается слушатель и вы передает типы ваших участников в параметры (cbType) то в обработчике эти участники будут идти именно в этом порядке.
Напр.,

...
new InteractionListener(CbEvent.BEGIN, InteractionType.COLLISION, _cubeCBType, _platformCBType, beginHandler);
...
private function beginHandler(cb:InteractionCallback):void
{
    cb.int1 - будет соответствовать типу _cubeCBType
    cb.int2 - будет соответствовать типу _platformCBType
}

Вам больше не надо проверять кто есть кто, учитывая то, что вы можете слушать взаимодействия сложного тела и фигуры, это особенно важно.
Новая система отслеживания столкновения дает поистине широкие возможности по настройке и обработки взаимодействий.

 

Как правильно удалить слушатель из мира

Возьмем пример из кода выше.
Допустим после первого срабатывания обработчика вы хотите удалить этот слушатель, чтобы больше не отрабатывать это событие.
В объекте callback, который передается  в каждый обработчик, есть поле listener, который содержит ссылку на слушатель.
И для того, чтобы удалить его из мира достаточно присвоить свойству space слушателя null.

private function beginHandler(cb:InteractionCallback):void
{
    cb.listener.space = null;
}

Ну а если надо удалить всех слушателей тогда так:

cb.listener.space.listeners.clear();

Имейте ввиду один нюанс — если у вас подключены два слушателя напр. BEGINE и ONGONING, и в слушателе BEGINE вы удалили все слушатели, то обработчик ONGONING вызовется все равно.

 
Ну и на последок о методе space.clear()
Этот метод призван очищать полностью мир — удаляются все тела, связи, слушатели и все параметры скидываются по-умолчанию. Как сказал Лука все равно, что сделал new Space().
Недавно казус вышел у меня. Очистил я таким макаром мир и снова добавил тела в него. И вот тут смотрю симуляции не происходит. Сам не догадался и пошел у Луки спрашивать. Оказалось что и гравитация тоже сбросилась в (0, 0) :)
Вот такие дела.

Поделиться в соц. сетях

Опубликовать в LiveJournal
Опубликовать в Google Plus
  • xrapa

    а как в функции слушателя столкновений cbType понять, что это за тело статическое или динамическое

    • VirtualMaestro

      Для каждого типа события в слушатель передается свой параметр колбек, например, для коллизий это InteractionCallback. В нем есть два поля int1 и int2.

      Если есть уверенность в том, что это тела (это можно проверить — есть методы isBody, isShape ) тогда надо привести к Body и вызвать метод isStatic , private function collisionHandler(cb:InteractionCallback):voidкоторый и вернет true в случае если тело статическое —


      private function collisionHandler(cb:InteractionCallback):void
      {
      if (cb.int1.castBody.isStatic())
      {

      }
      }

  • xrapa

    Создаю боди, добавляю shapes, ставлю скорость. Потом когда надо очистить мир пиши space.clear(). Вроде бы все очистилось, но возращаясь в этот раздел на тело добавляется новый shapes или на тело добавляется новое тело и оно начинает быстрее летать. И так нажимая выход и назад тело быстрей и быстрей летает.

    • xrapa

      Простите, очень хотелось бы узнать как это сделать правильно.

      • VirtualMaestro

        Если честно я не понял вопрос.