@@ -21,81 +21,95 @@ The basics:
21
21
22
22
` EventListenerCustom ` - responds to custom events
23
23
24
- ## Creating a touch event
25
- FIXME: Introduce a very simple sample of touches, and the flow of the touch event... how it is handled by the different consumers
26
-
27
- FIXME: Then introduce the "swallow" property
24
+ ## FixedPriority vs SceneGraphPriority
28
25
29
- FIXME: Describe the chain of command.
26
+ The * EventDispatcher* uses priorities to decide which listeners get delivered an
27
+ event first.
30
28
31
- Touch events are the most important event in mobile gaming. They are easy to create
32
- and provide versatile functionality.
29
+ ` FixedPriority ` is an integer value. Event listeners with lower Priority values
30
+ get to process events before event listeners with higher Priority values.
31
+
32
+ ` SceneGraphPriority ` is a pointer to a ` Node ` . Event listeners whose _ Nodes_ have
33
+ higher _ z-order_ values (that is, are drawn on top) receive events before event
34
+ listeners whose _ Nodes_ have lower Z order values (that is, are drawn below).
35
+ This ensures that touch events, for example, get delivered front-to-back, as you
36
+ would expect.
37
+
38
+ Remember Chapter 2? Where we talked about the _ scene graph_ and we talked about
39
+ this diagram?
40
+
41
+ ![ ] ( 2/in-order-walk.png " in-order walk ")
42
+
43
+ Well, when use _ SceneGraphPriority_ you are actually walking this above tree
44
+ backwards... _ H_ , _ I_ , _ G_ , _ F_ , _ E_ , _ D_ , _ C_ , _ B_ , _ A_ . If an event is triggered,
45
+ _ H_ would take a look and either _ swallow_ it (more on this below) or let is pass
46
+ through to _ I_ . Same thing, _ I_ will either _ consume_ it or let is pass thought
47
+ to _ G_ .. and so on until the event either _ swallowed_ or it does not get answered.
48
+
49
+ ## Touch Events
50
+ Touch events are the most important event in mobile gaming. They are easy to
51
+ create and provide versatile functionality. Let's make sure we know what a touch
52
+ event is. When you touch the screen of your mobile device, it accepts the touch,
53
+ looks at where you touched and decides what you touched. Your touch is then answered.
54
+ It is possible that what you touched might not be the responding object but perhaps
55
+ something underneath it. Touch events are usually assigned a priority and the
56
+ event with the highest priority is the one that answers. Here is how you create
57
+ a basic touch event listener:
33
58
``` cpp
34
59
// Create a "one by one" touch event listener
35
60
// (processes one touch at a time)
36
61
auto listener1 = EventListenerTouchOneByOne::create();
37
62
38
- // When "swallow touches" is true, then returning 'true' from the
39
- // onTouchBegan method will "swallow" the touch event, preventing
40
- // other listeners from using it.
41
- listener1->setSwallowTouches (true);
42
-
43
- // use a lambda!
63
+ // trigger when you push down
44
64
listener1->onTouchBegan = [](Touch* touch, Event* event){
45
- // event->getCurrentTarget() returns the * listener's*
46
- // sceneGraphPriority node.
47
- auto target = static_cast<Sprite* >(event->getCurrentTarget());
48
-
49
- //Get the position of the current point relative to the button
50
- Point locationInNode = target->convertToNodeSpace(touch->getLocation());
51
- Size s = target->getContentSize();
52
- Rect rect = Rect(0, 0, s.width, s.height);
53
-
54
- //Check the click area
55
- if (rect.containsPoint(locationInNode))
56
- {
57
- log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
58
-
59
- return true;
60
- }
61
- return false;
62
- };
63
-
64
- // Trigger when moving touch
65
- listener1->onTouchMoved = [](Touch* touch, Event* event){
66
- auto target = static_cast<Sprite*>(event->getCurrentTarget());
67
-
68
- // Note: touch->getDelta(); will provide change in movement.
69
- };
70
-
71
- // Process the touch end event
72
- listener1->onTouchEnded = [=](Touch* touch, Event* event){
73
- auto target = static_cast<Sprite*>(event->getCurrentTarget());
74
- log("sprite onTouchesEnded.. ");
75
- };
76
- ```
65
+ // your code
66
+ };
77
67
78
- As you can see there are 3 distinct events that you can act upon when using a touch event
79
- listener. They each have a distinct time in which they are called.
68
+ // trigger when moving touch
69
+ listener1->onTouchMoved = [](Touch* touch, Event* event){
70
+ // your code
71
+ };
72
+
73
+ // trigger when you let up
74
+ listener1->onTouchEnded = [=](Touch* touch, Event* event){
75
+ // your code
76
+ };
77
+
78
+ // Add listener
79
+ _eventDispatcher->addEventListenerWithSceneGraphPriority (listener1, this);
80
+ ```
81
+ As you can see there are 3 distinct events that you can act upon when using a
82
+ touch event listener. They each have a distinct time in which they are called.
80
83
81
84
`onTouchBegan` is triggered when you press down.
82
85
83
- `onTouchMoved` is triggered if you move the object around while still pressing down.
86
+ `onTouchMoved` is triggered if you move the object around while still pressing
87
+ down.
84
88
85
89
`onTouchEnded` is triggered when you let up on the touch.
86
90
87
- FIXME: Don't add obj-c code
91
+ ## Swallowing Events
92
+ When you have a listener and you want an object to accept the event it was given
93
+ you must _swallow_ it. In other words you _comsume_ it so that it doesn't get
94
+ passed to other objects in highest to lowest priority. This is easy to do.
95
+ ```cpp
96
+ // When "swallow touches" is true, then returning 'true' from the
97
+ // onTouchBegan method will "swallow" the touch event, preventing
98
+ // other listeners from using it.
99
+ listener1->setSwallowTouches(true);
88
100
89
- Also, it is possible to enable *multi-touch*. This is the ability to touch the screen with
90
- multiple fingers at the same time and have every object you touch respond to its listeners.
91
- On iOS *multi-touch* is disabled by default. You will need to enable it by adding
92
- `[eaglView setMultipleTouchEnabled:YES];` in the `AppDelegate.mm` class. Andorid platforms
93
- have *milti-touch* turned on by default.
101
+ // you should also return true in onTouchBegan()
94
102
103
+ listener1->onTouchBegan = [](Touch* touch, Event* event){
104
+ // your code
105
+
106
+ return true;
107
+ };
108
+ ```
95
109
## Creating a keyboard event
96
110
For dekstop games, you might want find using keyboard mechanics useful.
97
111
Cocos2d-x supports keyboard events. Just like with touch events above,
98
- keyboard events are wasy to create.
112
+ keyboard events are easy to create.
99
113
``` cpp
100
114
// creating a keyboard event listener
101
115
auto listener = EventListenerKeyboard::create();
@@ -117,17 +131,19 @@ void KeyboardTest::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event)
117
131
```
118
132
119
133
## Creating an accelerometer event
120
- Some mobile devices come equipped with an accelerometer. An accelerometer is a sensor
121
- that measures g-force as well as changes in direction. A use case would be needing to
122
- move your phone back and forth, perhaps to simulate a balancing act.
134
+ Some mobile devices come equipped with an accelerometer. An accelerometer is a
135
+ sensor that measures g-force as well as changes in direction. A use case would
136
+ be needing to move your phone back and forth, perhaps to simulate a balancing act.
123
137
Cocos2d-x also supports these events and creating them is simple.
124
138
Before using accelerometer events, you need to enable them on the device:
125
139
```cpp
126
140
Device::setAccelerometerEnabled(true);
127
141
```
128
142
``` cpp
129
143
// creating an accelerometer event
130
- auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(AccelerometerTest::onAcceleration, this));
144
+ auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(
145
+ AccelerometerTest::onAcceleration, this ));
146
+
131
147
_eventDispatcher->addEventListenerWithSceneGraphPriority (listener, this);
132
148
133
149
// Implementation of the accelerometer callback function prototype
@@ -182,10 +198,10 @@ void MouseTest::onMouseScroll(Event *event)
182
198
```
183
199
184
200
## Creating a custom event listener
185
- The event types above are defined by the system, and the events are triggered by the system
186
- automatically. In addition, you can make your own custom events which are triggered by your
187
- code and not the system. These are called `Custom Events`. It is easy to use a `lambda` to
188
- house the functionality of these events.
201
+ The event types above are defined by the system, and the events are triggered by
202
+ the system automatically. In addition, you can make your own custom events which
203
+ are triggered by your code and not the system. These are called ` Custom Events ` .
204
+ It is easy to use a ` lambda ` to house the functionality of these events.
189
205
190
206
``` cpp
191
207
_listener = EventListenerCustom::create(" game_custom_event1" , [=](EventCustom* event){
@@ -216,35 +232,25 @@ _eventDispatcher->dispatchEvent(&event);
216
232
217
233
CC_SAFE_DELETE_ARRAY(buf);
218
234
```
219
- <<<<<<< HEAD
220
- The above example creates an ` EventCustom ` object and sets its ` UserData ` . It is then
221
- dispatched manually with ` _eventDispatcher->dispatchEvent(&event); ` . This triggers the
222
- event handler for your custom event.
223
- =======
224
- The above example creates an ` EventCustom ` object and sets its ` UserData ` . It is then dispatched
225
- manually with ` _eventDispatcher->dispatchEvent(&event); ` . This triggers the event handler for your
226
- custom event.
227
- >>>>>>> dd4d7b64e4ad973da07350f7333e4e3f940f31d1
235
+ The above example creates an `EventCustom` object and sets its `UserData`. It is
236
+ then dispatched manually with `_eventDispatcher->dispatchEvent(&event);`. This
237
+ triggers the event handler for your custom event.
228
238
229
239
## Registering event with the dispatcher
230
- It is easy to register an event with the * Event Dispatcher* . Taking the sample touch
231
- event listener from above:
240
+ It is easy to register an event with the *Event Dispatcher*. Taking the sample
241
+ touch event listener from above:
232
242
```cpp
233
243
// Add listener
234
244
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1,
235
245
sprite1);
236
246
```
237
- It is important to note that a touch event can only be reigstered once per object.
247
+ It is important to note that a touch event can only be registered once per object.
238
248
If you need to use the same listener for multiple objects you should
239
249
use ` clone() ` .
240
250
``` cpp
241
251
// Add listener
242
- <<<<<<< HEAD
243
- _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
244
- =======
245
252
_eventDispatcher->addEventListenerWithSceneGraphPriority (listener1,
246
253
sprite1);
247
- >>>>>>> dd4d7b64e4ad973da07350f7333e4e3f940f31d1
248
254
249
255
// Add the same listener to multiple objects.
250
256
_ eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(),
@@ -253,36 +259,12 @@ _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(),
253
259
_ eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(),
254
260
sprite3);
255
261
```
256
-
257
- ## FixedPriority vs SceneGraphPriority
258
-
259
- FIXME: Add graphics, explain that SceneGraph goes from foreground to background, reference Chapter 2, etc.
260
-
261
- The * EventDispatcher* uses priorities to decide which listeners get delivered an
262
- event first.
263
-
264
- ` FixedPriority ` is an integer value. Event listeners with lower Priority values get
265
- to process events before event listeners with higher Priority values.
266
-
267
- ` SceneGraphPriority ` is a pointer to a ` Node ` . Event listeners whose * Nodes* have higher
268
- Z order values (that is, are drawn on top) receive events before event listeners whose
269
- * Nodes* have lower Z order values (that is, are drawn below). This ensures that touch
270
- events, for example, get delivered front-to-back, as you would expect.
271
-
272
262
## Removing events from the dispatcher
273
263
An added listener can be removed with following method:
274
264
```cpp
275
265
_eventDispatcher->removeEventListener(listener);
276
266
```
277
- To remove all the listeners of the *event dispatcher*:
278
- ```cpp
279
- _eventDispatcher->removeAllEventListeners();
280
- ```
281
-
282
- FIXME: Say that some built-in nodes uses the event dispatcher, like Menu.
283
-
284
- FIXME: I don't know if we need to mention removeAllEventListener()
285
-
286
- When using ` removeAllEventListeners() ` , all the listeners for this node will be removed.
287
- Removing a specific listener is the recommended way. After using ` removeAllEventListeners() `
288
- even ` Menu ` objects can not respond, because the events that are triggered are also removed.
267
+ Although they may seem special, built-in ` Node ` objects use the _ event dispatcher_
268
+ in the same way we have talked out. Makes senese right? Take ` Menu ` for an example.
269
+ When you have a ` Menu ` with ` MenuItems ` when you click them you are dispatching a
270
+ event. You can also ` removeEventListener() ` on built-in ` Node ` objects.
0 commit comments