-
Notifications
You must be signed in to change notification settings - Fork 43
cocos2d x 3.3 009 核心概念和相关类 层
cheyiliu edited this page Jan 19, 2015
·
5 revisions
- 继承自Node
- 成员有键盘、touch、加速仪的事件监听器和事件相关的几个状态变量,那肯定和这些事件的监听相关了
bool _touchEnabled; bool _accelerometerEnabled; bool _keyboardEnabled; EventListener* _touchListener; EventListenerKeyboard* _keyboardListener; EventListenerAcceleration* _accelerationListener; Touch::DispatchMode _touchMode; bool _swallowsTouches;
- "乱花渐欲迷人眼"阿,头文件里各种CC_DEPRECATED_ATTRIBUTE, final修饰, 忽略掉对应的方法就好
//touch
virtual bool onTouchBegan(Touch *touch, Event *unused_event);
virtual void onTouchMoved(Touch *touch, Event *unused_event);
virtual void onTouchEnded(Touch *touch, Event *unused_event);
virtual void onTouchCancelled(Touch *touch, Event *unused_event);
virtual void onTouchesBegan(const std::vector<Touch*>& touches, Event *unused_event);
virtual void onTouchesMoved(const std::vector<Touch*>& touches, Event *unused_event);
virtual void onTouchesEnded(const std::vector<Touch*>& touches, Event *unused_event);
virtual void onTouchesCancelled(const std::vector<Touch*>&touches, Event *unused_event);
//acceleration
virtual void onAcceleration(Acceleration* acc, Event* unused_event);
//key
virtual void onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event);
virtual void onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event);
1.上述的onTouchXXX onAcceleration onKeyXXX
全部代码都类似下面,实现脚本语言的事件处理
#if CC_ENABLE_SCRIPT_BINDING
if(kScriptTypeNone != _scriptType)
{
ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);
}
#endif
2. _touchEnabled相关
/// isTouchEnabled setter
void Layer::setTouchEnabled(bool enabled)
{
//值真的变了才处理
if (_touchEnabled != enabled)
{
_touchEnabled = enabled;
if (enabled)
{
if (_touchListener != nullptr)
return;
//all at once 类型, 设置对应的监听器, 多点触摸
if( _touchMode == Touch::DispatchMode::ALL_AT_ONCE )
{
// Register Touch Event
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesBegan = CC_CALLBACK_2(Layer::onTouchesBegan, this);
listener->onTouchesMoved = CC_CALLBACK_2(Layer::onTouchesMoved, this);
listener->onTouchesEnded = CC_CALLBACK_2(Layer::onTouchesEnded, this);
listener->onTouchesCancelled = CC_CALLBACK_2(Layer::onTouchesCancelled, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
_touchListener = listener;
}
else
{
//one by one mode, 单点触摸监听设置
// Register Touch Event
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(_swallowsTouches);
listener->onTouchBegan = CC_CALLBACK_2(Layer::onTouchBegan, this);
listener->onTouchMoved = CC_CALLBACK_2(Layer::onTouchMoved, this);
listener->onTouchEnded = CC_CALLBACK_2(Layer::onTouchEnded, this);
listener->onTouchCancelled = CC_CALLBACK_2(Layer::onTouchCancelled, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
_touchListener = listener;
}
}
else
{
//disable 则移除监听器
_eventDispatcher->removeEventListener(_touchListener);
_touchListener = nullptr;
}
}
}
3._accelerometerEnabled相关
void Layer::setAccelerometerEnabled(bool enabled)
{
if (enabled != _accelerometerEnabled)
{
_accelerometerEnabled = enabled;
Device::setAccelerometerEnabled(enabled);
//先移除
_eventDispatcher->removeEventListener(_accelerationListener);
_accelerationListener = nullptr;
if (enabled)
{
//设置监听器
_accelerationListener = EventListenerAcceleration::create(CC_CALLBACK_2(Layer::onAcceleration, this));
_eventDispatcher->addEventListenerWithSceneGraphPriority(_accelerationListener, this);
}
}
}
4._keyboardEnabled相关
/// isKeyboardEnabled setter
void Layer::setKeyboardEnabled(bool enabled)
{
if (enabled != _keyboardEnabled)
{
_keyboardEnabled = enabled;
//移除
_eventDispatcher->removeEventListener(_keyboardListener);
_keyboardListener = nullptr;
if (enabled)
{
auto listener = EventListenerKeyboard::create();
listener->onKeyPressed = CC_CALLBACK_2(Layer::onKeyPressed, this);
listener->onKeyReleased = CC_CALLBACK_2(Layer::onKeyReleased, this);
//设置
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
_keyboardListener = listener;
}
}
}
5. _swallowsTouches相关
5.1 默认值true
5.2 在void Layer::setTouchEnabled(bool enabled)过程中,
针对单点事件时, listener->setSwallowTouches(_swallowsTouches);
最后调用到了void EventListenerTouchOneByOne::setSwallowTouches(bool needSwallow)
这个值的最终用处是在CEventDispatcher.cpp, dispatchTouchEvent方法中, 结合dispatchEventToListeners
的代码看
{
设置needSwallow=true后, 在dispatchEventToListeners的参数onEvent将会返回true,
事件派发的循环将break,
导致剩下的事件监听器接受不到事件,从而实现事件不被进一步传播
}
5.3 void Layer::setSwallowsTouches(bool swallowsTouches)
{
//值变化了才继续
if (_swallowsTouches != swallowsTouches)
{
_swallowsTouches = swallowsTouches;
if( _touchEnabled)
{
//若touch enabled则先设置enable为false,移除之前的监听器
//再重新设置监听器
setTouchEnabled(false);
setTouchEnabled(true);
}
}
}
- Layer层提供的默认事件处理是针对脚本引擎相关的,但接口是虚的,也即允许我们重写。
- 几个状态相关的变量都是设置监听器或者取消监听器
- setSwallowsTouches设置之后,在事件分发器生效,大致过程是, 在one by one(单点) touch的事件分发时,若设置了swallowTouch,在分发遍过程中,遍历监听器时会导致循环break,从而导致事件不被进一步传播
Just build something.