Let’s compare the new version with 2.X for this question: a delegate is needed to handle events in 2.x. I believe students who have studied touch events in 2.x know the process of creation and removal. Very cumbersome. In 3.x, due to the addition of C++11 features, the event distribution mechanism is managed uniformly through the event dispatcher EventDispatcher.
The main event listeners are:
Touch events: EventListenerTouchOneByOne, EventListenerTouchAllAtOnce
Mouse response event: EventListenerMouse
Keyboard response events: EventListenerKeyboard
Accelerometer events: EventListenerAcceleration
Custom event: EventListenerCustom
Physics collision events: EventListenerPhysicsContact
Gamepad events: EventListenerController
【Event Distributor】
The event dispatcher EventDispatcher is used to uniformly manage the distribution of all events of the event listener.
1、_eventDispatcher
_eventDispatcher is a property of Node, which is obtained through Director::getInstance()->getEventDispatcher().
The work of _eventDispatcher consists of three parts:
(1) Event distributor: EventDispatcher.
(2) Event types: EventTouch, EventKeyboard, etc.
(3) Event listeners: EventListenerTouch, EventListenerKeyboard, etc.
The listener implements various triggered logics. When appropriate, the event dispatcher distributes the event type, and then calls the corresponding type of listener.
2. Add/remove listeners
Add listeners: addEventListenerWithSceneGraphPriority, addEventListenerWithFixedPriority.
Remove listeners: removeEventListener, removeAllEventListeners.
3. Main functions
Including the addition, deletion, suspension, and resumption of listeners, priority setting, manual event distribution, etc.
//
class EventDispatcher : public Ref
{
/**
* Add a listener
* - addEventListenerWithSceneGraphPriority
* - addEventListenerWithFixedPriority
* - addCustomEventListener
*/
//Use the priority of the scene graph to add a listener for the specified event.
//listener: Specify the event to be monitored.
//node: The drawing order of this node is based on monitoring priority.
//Priority: 0
void addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node);
//Use a certain priority to add a listener for the specified event.
//listener: Specify the event to be monitored.
//fixedPriority: The fixed priority of this listener.
//Priority: fixedPriority. (But it cannot be 0, because it is the basic priority of the scene graph)
void addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority);
//User-defined listener
EventListenerCustom* addCustomEventListener(const std::string &eventName, const std::function& callback);
/**
* Delete the listener
* - removeEventListener
* - removeEventListenersForType
* - removeEventListenersForTarget
* - removeCustomEventListeners
* - removeAllEventListeners
*/
//Delete the specified listener
void removeEventListener(EventListener* listener);
//Delete all listeners corresponding to a certain type
//EventListener::Type::
// Single touch: TOUCH_ONE_BY_ONE
// Multi-touch: TOUCH_ALL_AT_ONCE
// Keyboard: KEYBOARD
// Mouse: MOUSE
// Accelerometer: ACCELERATION
// Custom: CUSTOM
void removeEventListenersForType(EventListener::Type listenerType);
//Delete all listeners bound to the node target
void removeEventListenersForTarget(Node* target, bool recursive = false);
//Delete all custom listeners whose name is customEventName
void removeCustomEventListeners(const std::string& customEventName);
//Remove all listeners
void removeAllEventListeners();
/**
* Pause and resume all listeners on the node target
* - pauseEventListenersForTarget
* - resumeEventListenersForTarget
*/
void pauseEventListenersForTarget(Node* target, bool recursive = false);
void resumeEventListenersForTarget(Node* target, bool recursive = false);
/**
* Other
* - setPriority
* - setEnabled
* - dispatchEvent
* - dispatchCustomEvent
*/
//Set the priority of a listener
void setPriority(EventListener* listener, int fixedPriority);
//Enable event dispatcher
void setEnabled(bool isEnabled);
bool isEnabled() const;
//Manually dispatch custom events
void dispatchEvent(Event* event);
// Bind user data to a custom listener named eventName
void dispatchCustomEvent(const std::string &eventName, void *optionalUserData = nullptr);
}
//
4. About the priority of event listeners
The listener added by addEventListenerWithSceneGraphPriority has a priority of 0.
The priority of the listener added by addEventListenerWithFixedPriority can be customized, but it cannot be 0.
The lower the priority, the first to respond to events.
If the priority is the same, the upper layer (z axis) receives the touch event first.
5. Use steps
(1) Get the event dispatcher: dispatcher = Director::getInstance()->getEventDispatcher();
(2) Create a listener: auto listener = EventListenerTouchOneByOne::create();
(3) Binding response event function: listener->onTouchBegan = CC_CALLBACK_2(callback, this);
(4) Add the listener to the event dispatcher: dispatcher->addEventListenerWithSceneGraphPriority(Listener, this);
(5) Write callback response function: bool callback(Touch* touch, Event* event) {...}
【Touch Event】
1. Single touch: EventListenerTouchOneByOne
Single touch monitor related:
//
static EventListenerTouchOneByOne* create();
std::function onTouchBegan; //Only this return value is bool
std::function onTouchMoved;
std::function onTouchEnded;
std::function onTouchCancelled;
//
Examples of use:
//
//Get event dispatcher
auto dispatcher = Director::getInstance()->getEventDispatcher();
//Create a single touch listener EventListenerTouchOneByOne
auto touchListener = EventListenerTouchOneByOne::create();
//Single touch response event binding
touchListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
touchListener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this);
touchListener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
touchListener->onTouchCancelled = CC_CALLBACK_2(HelloWorld::onTouchCancelled, this);
//In the event dispatcher, add a touch listener, and delegate the event response to this
dispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
//Single touch event response function
bool onTouchBegan(Touch *touch, Event *unused_event) { CCLOG("began"); return true; }
void onTouchMoved(Touch *touch, Event *unused_event) { CCLOG("moved"); }
void onTouchEnded(Touch *touch, Event *unused_event) { CCLOG("ended"); }
void onTouchCancelled(Touch *touch, Event *unused_event) { CCLOG("cancelled"); }
//
2. Multi-touch: EventListenerTouchAllAtOnce
Multi-touch monitor related:
//
static EventListenerTouchAllAtOnce* create();
std::function&, Event*)> onTouchesBegan;
std::function&, Event*)> onTouchesMoved;
std::function&, Event*)> onTouchesEnded;
std::function&, Event*)> onTouchesCancelled;
//
Examples of use:
//
//Get event dispatcher
auto dispatcher = Director::getInstance()->getEventDispatcher();
//Create a multi-touch listener EventListenerTouchAllAtOnce
auto touchesListener = EventListenerTouchAllAtOnce::create();
//Multi-touch response event binding
touchesListener->onTouchesBegan = CC_CALLBACK_2(HelloWorld::onTouchesBegan, this);
touchesListener->onTouchesMoved = CC_CALLBACK_2(HelloWorld::onTouchesMoved, this);
touchesListener->onTouchesEnded = CC_CALLBACK_2(HelloWorld::onTouchesEnded, this);
touchesListener->onTouchesCancelled = CC_CALLBACK_2(HelloWorld::onTouchesCancelled, this);
//In the event dispatcher, add a touch listener, and delegate the event response to this
dispatcher->addEventListenerWithSceneGraphPriority(touchesListener, this);
//Multi-touch event response function
void onTouchesBegan(const std::vector& touches, Event *unused_event) { CCLOG("began"); }
void onTouchesMoved(const std::vector& touches, Event *unused_event) { CCLOG("moved"); }
void onTouchesEnded(const std::vector& touches, Event *unused_event) { CCLOG("ended"); }
void onTouchesCancelled(const std::vector&touches, Event *unused_event) { CCLOG("cancelled"); }
//
【Mouse Event】
EventListenerMouse is mainly used to monitor events of mouse click, release, movement, and scroll wheel.
Mouse event listener related:
//
static EventListenerMouse* create();
std::function onMouseDown; //Press the mouse, click the mouse
std::function onMouseUp; //Release the mouse, and release it when pressed
std::function onMouseMove; //Move the mouse, move on the screen
std::function onMouseScroll;//Scroll the mouse, scroll the mouse wheel
//
Examples of use:
//
//Get event dispatcher
auto dispatcher = Director::getInstance()->getEventDispatcher();
//Create a mouse event listener EventListenerMouse
EventListenerMouse* mouseListenter = EventListenerMouse::create();
//Mouse event response function
mouseListenter->onMouseDown = CC_CALLBACK_1(HelloWorld::onMouseDown, this);
mouseListenter->onMouseUp = CC_CALLBACK_1(HelloWorld::onMouseUp, this);
mouseListenter->onMouseMove = CC_CALLBACK_1(HelloWorld::onMouseMove, this);
mouseListenter->onMouseScroll = CC_CALLBACK_1(HelloWorld::onMouseScroll, this);
//Add a mouse event listener, and delegate the event response processing to this
dispatcher->addEventListenerWithSceneGraphPriority(mouseListenter, this);
//Event response function
void onMouseDown(Event* event) { CCLOG("Down"); }
void onMouseUp(Event* event) { CCLOG("UP"); }
void onMouseMove(Event* event) { CCLOG("MOVE"); }
void onMouseScroll(Event* event) { CCLOG("Scroll"); }
//
【Keyboard Event】
EventListenerKeyboard is mainly used to monitor the pressing and releasing of a key on the keyboard.
Keyboard event listener related:
//
static EventListenerKeyboard* create();
std::function onKeyPressed; //Press a key
std::function onKeyReleased; //Release a key
//Keyboard key enumeration type EventKeyboard::KeyCode
//The value of KeyCode corresponds to neither the keyboard key nor the ASCII code, but a purely enumerated type
//Such as:
// EventKeyboard::KeyCode::KEY_A
// EventKeyboard::KeyCode::KEY_1
// EventKeyboard::KeyCode::KEY_F1
// EventKeyboard::KeyCode::KEY_SPACE
// EventKeyboard::KeyCode::KEY_ALT
// EventKeyboard::KeyCode::KEY_SHIFT
//
Examples of use:
//
//Get event dispatcher
auto dispatcher = Director::getInstance()->getEventDispatcher();
//Create a keyboard key event listener
EventListenerKeyboard* keyboardListener = EventListenerKeyboard::create();
//Binding event response function
keyboardListener->onKeyPressed = CC_CALLBACK_2(HelloWorld::onKeyPressed, this);
keyboardListener->onKeyReleased = CC_CALLBACK_2(HelloWorld::onKeyReleased, this);
//Add a listener
dispatcher->addEventListenerWithSceneGraphPriority(keyboardListener, this);
//Event response function
void onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event) {
if (EventKeyboard::KeyCode::KEY_J == keyCode) {
CCLOG("Pressed: J");
}
}
void onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event) {
if (EventKeyboard::KeyCode::KEY_SPACE == keyCode) {
CCLOG("Released: SPACE");
}
}
//
【Accelerometer Event】
EventListenerAcceleration is mainly used to monitor the gravity direction sensing events of mobile devices.
Gravity sensing comes from the accelerometer of a mobile device, which usually supports acceleration sensing in three directions (X, Y, Z), so it is also called a three-way accelerometer. In practical applications, the angle or direction of the inclination of the mobile phone can be calculated according to the strength of the three directions.
1. Acceleration
The magnitude of acceleration in each direction in this category is a magnitude of gravity acceleration.
//Accelerometer information
class Acceleration
{
double x; double y; double z;
};
//
2. Turn on accelerometer sensing
Before using the accelerometer event listener, you need to enable this hardware device:
1 Device::setAccelerometerEnabled(true);
3. Accelerometer monitor related
//
static EventListenerAcceleration* create(const std::function& callback);
std :: function onAccelerationEvent;
//
4. Examples of use
//
//Label: display accelerometer information
label = Label::createWithTTF("no used", "Marker Felt.ttf", 12);
label->setPosition(visibleSize / 2);
this->addChild(label);
//Small ball: visual accelerometer
ball = Sprite::create("ball.png");
ball->setPosition(visibleSize / 2);
this->addChild(ball);
//Get event dispatcher
auto dispatcher = Director::getInstance()->getEventDispatcher();
//Need to turn on the accelerometer of the mobile device
Device::setAccelerometerEnabled(true);
//Create an accelerometer event listener
auto accelerationListener = EventListenerAcceleration::create(CC_CALLBACK_2(HelloWorld::onAccelerationEvent, this));
//Add accelerometer listener
dispatcher->addEventListenerWithSceneGraphPriority(accelerationListener, this);
//Event response function
void HelloWorld::onAccelerationEvent(Acceleration* acceleration, Event* event)
{
char s[100];
sprintf(s, "X: %f; Y: %f; Z:%f; ", acceleration->x, acceleration->y, acceleration->z);
label->setString(s);
//Change the position of the ball
float x = ball->getPositionX() + acceleration->x * 10;
float y = ball->getPositionY() + acceleration->y * 10;
Vec2 pos = Vec2 (x, y);
pos.clamp(ball->getContentSize() / 2, Vec2(288, 512) - ball->getContentSize() / 2);
ball->setPosition(pos); //Set position
}
//
5. Actual effect
The effect is not visible on the computer, and it needs to be transplanted to the mobile phone to see the effect of the accelerometer.
【Custom Event】
The above are the types of events that come with the system. The events are automatically triggered by the system, such as touching the screen and responding to the keyboard.
EventListenerCustom custom event, it is not automatically triggered by the system, but human intervention.
1. Create a custom listener
//
//eventName: listener name
//callback: listener function
static EventListenerCustom* create(const std::string& eventName, const std::function& callback);
//
2. Distribute custom events
A custom event listener needs to be distributed manually.
Get a custom listener through EventCustom(string eventName);.
Distribute the event manually through dispatcher->dispatchEvent(&event);.
//
EventCustom event("your_event_type");
dispatcher->dispatchEvent(&event);
//
3. Examples of use
//
//Get event dispatcher
auto dispatcher = Director::getInstance()->getEventDispatcher();
//Create a custom event listener
//Listener name: "custom_event"
//Event response function: HelloWorld::onCustomEvent
auto customListener = EventListenerCustom::create("custom_event", CC_CALLBACK_1(HelloWorld::onCustomEvent, this));
//Add a custom event listener, priority is 1
dispatcher->addEventListenerWithFixedPriority(customListener, 1);
//Manually distribute the events of the listener through dispatchEvent
EventCustom event = EventCustom("custom_event");
dispatcher->dispatchEvent(&event);
//Event response function
void HelloWorld::onCustomEvent(EventCustom* event)
{
CCLOG("onCustomEvent");
}
//
4. Description
Each custom event listener has a listener name eventName.
You need to manually dispatch the event through dispatcher->dispatchEvent(&event);.
You can use dispatcher->dispatchCustomEvent(,); to bind a custom event listener with user data.