简体   繁体   中英

Touch Event on Sprite with Cocos2d-x 3.x?

In my scene I have a vector with multiple custom sprites. When I tap on one of them, I want an action to be fired on another element on the scene, can be another sprite in the vector, or another node. I have been researching the best way to do this, but I'm not quite sure how to implement it. The options are:

  • Add a touch listener to the scene, and verify if it was tapped inside the bounds of the sprite with rect. containsPoint(point) rect. containsPoint(point) . And after that, I have to get the sprite that was tapped to do the action I want. For me, it doesn't seems very clean to do it this way. And if two sprites are overlaped, I have to verify if the sprite is behind or in the front in order to retrieve the desired sprite. I followed this example: Touch Event example

  • Add a touch listener in the subclass of the sprite (my custom sprite). And add onTouchBegan and onTouchEnded inside it. But this way, I don't know how to modify an attribute of another sprite, or another element in the scene (Is it possible to use Delegates like Objective-C does?). I followed this example: Subclass Sprite Example

My main problem is that I don't understand very well how to make a node interact with another node in the scene. I have seen a lot of tutorials, but in all of them, when you interact with a node, it only changes its attributes, not other nodes' attributes.

Thanks in advance.

I shall propose "EventCustom" way :)

You can add in your touchBegan / touchEnded methods (wherever you put them... you got the point...) additional code for passing an EventCusto to the _eventDispatcher and get it announced to the world ;)

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

You may subclass the EventCustom class but that is hardly necessary. You can always hang an object to it with setUserData().

Now the objects which need to react to the event can listen to it by

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

It's always a good practice to remove your listeners when you go off, so somewhere, perhaps in onExit(), where you removed touch listeners remove this listener too, as

_eventDispatcher->removeEventListener(_myCustomListener);

Going a bit off the track, a clarification: CC_CALLBACK_X are a bit tricky names. The X indicates the no. of args the target function will get. Here, event dispatcher will pass 1 arg ie ptr to object of EventCustom you handed it, so we use CC_CALLBACK_1. The next arg - here "this" - is the object on which the method will be invoked. In short, we may say that this callback is going to result into a function call this->onMyAwesomeEvent(e);

For CC_CALLBACK_2 onwards, we can specify additional args, 3rd arg onwards.

Coming back to the issue at hand, ListeningClass::onMyAwesomeEvent will look something like

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

Hope it helps :)

Set your elements tags or names with setTag and setName . Then if element x is touched, get them with getChildByTag or getChildByName and do what you need to do.

With the second option you list above. To make a node interact with another node in the scene you can add touch callback function to your custom sprite object like that: https://github.com/Longpc/RTS/tree/master/Classes/base/dialogBase

and in main scene you can define function to handle this callback. So you can do every thing to unit in you scene

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM