Cocos2d-x 3.x basic learning: summary of new event distribution mechanism

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.

Guess you like

Origin blog.csdn.net/qq_21743659/article/details/108637109