2016-01-25 2 views
1

В моей сцене у меня есть вектор с несколькими пользовательскими спрайтами. Когда я нажимаю на один из них, я хочу, чтобы действие было запущено на другом элементе на сцене, может быть другим спрайтом в векторе или другом узле. Я изучал лучший способ сделать это, но я не совсем уверен, как его реализовать. Варианты:Touch Event на Sprite с Cocos2d-x 3.x?

  • Добавить сенсорную слушателя на сцену, и проверить, если он был использован в рамках спрайта с rect. containsPoint(point). И после этого, я должен получить спрайт, который был использован, чтобы выполнить действие, которое я хочу. Для меня это не кажется очень чистым, чтобы сделать это таким образом. И если два спрайта перекрываются, я должен проверить, находится ли спрайт позади или спереди, чтобы получить желаемый спрайт. Я следовал этому примеру: Touch Event example

  • Добавить прослушиватель прикосновений в подкласс спрайта (мой собственный спрайт). И добавьте onTouchBegan и onTouchEnded внутри него. Но таким образом я не знаю, как изменить атрибут другого спрайта или другого элемента в сцене (возможно ли использовать такие делегаты, как Objective-C?). Я последовал этому примеру: Subclass Sprite Example

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

Заранее спасибо.

+0

Вы можете разместить полный минимальный пример кодов? – Raptor

+0

@Raptor Обновлен мой вопрос. У меня такой же код, как и в приведенных ссылках. –

ответ

0

Задайте свои элементы тегами или именами с помощью setTag и setName. Затем, если элемент x коснулся, получите их с getChildByTag или getChildByName и сделайте то, что вам нужно сделать.

0

Со вторым вариантом, указанным выше. Чтобы сделать узел взаимодействует с другим узлом в сцене, вы можете добавить сенсорную функцию обратного вызова для пользовательского объекта спрайтов так: https://github.com/Longpc/RTS/tree/master/Classes/base/dialogBase

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

1

Я предлагаю «EventCustom» путь :)

Вы можете добавить в ваши touchBegan/touchEnded методов (там, где вы их ... вы получили точку. ..) дополнительный код для прохождения EventCusto к _eventDispatcher и получить его объявили миру;)

EventCustom *e = new EventCustom("MyAwesomeEvent"); 
e->setUserData(ptrMyFantasticData); //This function takes a void pointer. cheers :) 
_eventDispatcher->dispatchEvent(e); 

Вы можете создать подкласс класса EventCustom, но это вряд ли необходимо. Вы всегда можете повесить объект с помощью setUserData().

Теперь объекты, которые должны реагировать на событие может слушать его на

_myCustomListener = EventListenerCustom::create(
       "MyAwesomeEvent", 
       CC_CALLBACK_1(
        ListeningClass::onMyAwesomeEvent, 
        this 
       ) 
      ); 
_eventDispatcher->addEventListenerWithXXXXXPriority(_myCustomListener, XXX); 
//ScreenGraphPriority/FixedPriority depends on situation. Either should work. 

Это всегда хорошая практика, чтобы удалить ваши слушатель, когда Вы уходите, так где-то, возможно, в OnExit(), где вы удалили сенсорные слушатель удалить этот приемник тоже, как

_eventDispatcher->removeEventListener(_myCustomListener); 

Забегая с трассой, разъяснения: CC_CALLBACK_X немного хитрые имена. X указывает на отсутствие. из аргументов будет получена целевая функция. Здесь диспетчер событий будет передавать 1 arg i.e.ptr к объекту EventCustom вы передали его, поэтому мы используем CC_CALLBACK_1. Следующий аргумент - здесь «это» - это объект, на который будет вызываться метод. Короче говоря, мы можем сказать, что этот обратный вызов приведет к вызову функции this->onMyAwesomeEvent(e);

Для CC_CALLBACK_2 и далее мы можем указать дополнительные аргументы, начиная с третьего аргумента.

Возвращаясь к вопросу под руку, ListeningClass :: onMyAwesomeEvent будет выглядеть как

void ListeningClass::onMyAwesomeEvent(EventCustom *e) 
{ 
    MyFantasticData *d = (MyFantasticData *) e->getUserData(); 
    CCLOG("[ListeningClass::onMyAwesomeEvent] %d", d->getMyPreciousInt()); 
} 

Надеется, что это помогает :)