Skip to content

Commit 409b687

Browse files
committed
continued edits
1 parent 246a5b3 commit 409b687

File tree

1 file changed

+89
-107
lines changed

1 file changed

+89
-107
lines changed

8.md

+89-107
Original file line numberDiff line numberDiff line change
@@ -21,81 +21,95 @@ The basics:
2121

2222
`EventListenerCustom` - responds to custom events
2323

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
2825

29-
FIXME: Describe the chain of command.
26+
The *EventDispatcher* uses priorities to decide which listeners get delivered an
27+
event first.
3028

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:
3358
```cpp
3459
// Create a "one by one" touch event listener
3560
// (processes one touch at a time)
3661
auto listener1 = EventListenerTouchOneByOne::create();
3762

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
4464
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+
};
7767

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.
8083
8184
`onTouchBegan` is triggered when you press down.
8285
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.
8488
8589
`onTouchEnded` is triggered when you let up on the touch.
8690
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);
88100
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()
94102
103+
listener1->onTouchBegan = [](Touch* touch, Event* event){
104+
// your code
105+
106+
return true;
107+
};
108+
```
95109
## Creating a keyboard event
96110
For dekstop games, you might want find using keyboard mechanics useful.
97111
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.
99113
```cpp
100114
// creating a keyboard event listener
101115
auto listener = EventListenerKeyboard::create();
@@ -117,17 +131,19 @@ void KeyboardTest::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event)
117131
```
118132
119133
## 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.
123137
Cocos2d-x also supports these events and creating them is simple.
124138
Before using accelerometer events, you need to enable them on the device:
125139
```cpp
126140
Device::setAccelerometerEnabled(true);
127141
```
128142
```cpp
129143
// 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+
131147
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
132148

133149
// Implementation of the accelerometer callback function prototype
@@ -182,10 +198,10 @@ void MouseTest::onMouseScroll(Event *event)
182198
```
183199

184200
## 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.
189205

190206
```cpp
191207
_listener = EventListenerCustom::create("game_custom_event1", [=](EventCustom* event){
@@ -216,35 +232,25 @@ _eventDispatcher->dispatchEvent(&event);
216232

217233
CC_SAFE_DELETE_ARRAY(buf);
218234
```
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.
228238
229239
## 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:
232242
```cpp
233243
// Add listener
234244
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1,
235245
sprite1);
236246
```
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.
238248
If you need to use the same listener for multiple objects you should
239249
use `clone()`.
240250
```cpp
241251
// Add listener
242-
<<<<<<< HEAD
243-
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
244-
=======
245252
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1,
246253
sprite1);
247-
>>>>>>> dd4d7b64e4ad973da07350f7333e4e3f940f31d1
248254

249255
// Add the same listener to multiple objects.
250256
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(),
@@ -253,36 +259,12 @@ _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(),
253259
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(),
254260
sprite3);
255261
```
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-
272262
## Removing events from the dispatcher
273263
An added listener can be removed with following method:
274264
```cpp
275265
_eventDispatcher->removeEventListener(listener);
276266
```
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

Comments
 (0)