目录
事件处理
- 事件源:场景中的对象,每个Node节点都可以触发事件
- 事件处理者:监听器
EventListener
,负责监控对象是否触发某个事件, 如果触发就执行相应的回调函数。 - 事件分发者:事件分发器
EventDispatcher
,负责分配事件监听器给对象
1. 事件分发
1.1 初始化场景
init函数
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
Vec2 center = Vec2(visibleSize.width / 2, visibleSize.height / 2);
//背景
auto bg = Sprite::create("BackgroundTile.png",
Rect(0,0,visibleSize.width,visibleSize.height));
Texture2D::TexParams tp = { GL_LINEAR,GL_LINEAR,GL_REPEAT,GL_REPEAT };//线性插值,重复平铺
bg->getTexture()->setTexParameters(tp);
bg->setPosition(center);
this->addChild(bg);
//放入三个精灵
auto boxA = Sprite::create("BoxA2.png");
boxA->setPosition(center + Vec2(-120, 120));
this->addChild(boxA, 10, BOX_A);
auto boxB = Sprite::create("BoxB2.png");
boxB->setPosition(center);
this->addChild(boxB, 11, BOX_B);
auto boxC = Sprite::create("BoxC2.png");
boxC->setPosition(center + Vec2(120, 120));
this->addChild(boxC, 12, BOX_C);
1.2 注册监听器到对象
onEnter函数
void HelloWorld::onEnter() {
Scene::onEnter();
//事件分发器
EventDispatcher* disp = Director::getInstance()->getEventDispatcher();
//单点触摸监听器
listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTBegan, this);
listener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTMoved, this);
listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTEnded, this);
//注册监听器
disp->addEventListenerWithSceneGraphPriority(listener, this->getChildByTag(BOX_A));
disp->addEventListenerWithSceneGraphPriority(listener->clone(), this->getChildByTag(BOX_B));
disp->addEventListenerWithSceneGraphPriority(listener->clone(), this->getChildByTag(BOX_C));
}
1.3 注销(移除)监听器
onExit()函数
void HelloWorld::onExit() {
Scene::onExit();
EventDispatcher* disp = Director::getInstance()->getEventDispatcher();
disp->removeEventListenersForTarget(this);//移除该场景中的所有监听器
}
2. 触摸事件
2.1 触摸开始
bool HelloWorld::onTBegan(Touch* touch, Event* event) {
auto target = static_cast<Sprite*>(event->getCurrentTarget());
Vec2 tworld = touch->getLocation();//获取触摸点的opengl世界座标
Vec2 tlocal = target->convertToNodeSpace(tworld);
auto size = target->getContentSize();
auto rect = Rect(0, 0, size.width, size.height);
if (rect.containsPoint(tlocal)) {
target->runAction(ScaleBy::create(0.1f, 1.2f));
return true;
}
return false;
}
2.2 触摸移动
void HelloWorld::onTMoved(Touch* touch, Event* event) {
log("onTouchMoved");
auto target = static_cast<Sprite*>(event->getCurrentTarget());
target->setPosition(target->getPosition() + touch->getDelta());
}
2.3 触摸结束
void HelloWorld::onTEnded(Touch* touch, Event* event) {
auto target = static_cast<Sprite*>(event->getCurrentTarget());
Vec2 tworld = touch->getLocation();//获取触摸点的opengl世界座标
Vec2 tlocal = target->convertToNodeSpace(tworld);
auto size = target->getContentSize();
auto rect = Rect(0, 0, size.width, size.height);
if (rect.containsPoint(tlocal)) {
target->runAction(ScaleTo::create(0.1f, 1.00f));
}
}
2.4 触摸取消
void HelloWorld::onTCancelled(Touch* touch, Event* event) {
}
3. 使用Lambda表达式
可以理解为匿名函数,参见键盘事件、鼠标事件中的例子。
[]中添加外部引用的变量。
4. 键盘事件
//键盘事件监听器
auto keyListener = EventListenerKeyboard::create();
keyListener->onKeyPressed = CC_CALLBACK_2(HelloWorld::keyPressed, this);
//使用匿名函数,lambda表达式
keyListener->onKeyReleased = [](EventKeyboard::KeyCode code, Event * event){
log("keyReleased keycode = %d", code);
};
//注册监听器
disp->addEventListenerWithSceneGraphPriority(keyListener, this);
回调函数:
void HelloWorld::keyPressed(EventKeyboard::KeyCode code, Event * event)
{
log("keyPressed keycode = %d", code);
}
5. 鼠标事件
onEnter函数中
//鼠标事件监听器
auto mouseListener = EventListenerMouse::create();
mouseListener->onMouseUp = [](Event* event) {
log("Mouse Up");
};
mouseListener->onMouseDown = [](Event* event) {
log("Mouse Down");
};
mouseListener->onMouseScroll = [](Event* event) {
log("Mouse Scroll");
};
mouseListener->onMouseMove = [](Event* event) {
log("Mouse Move");
};
//注册监听器
disp->addEventListenerWithSceneGraphPriority(mouseListener, this);
6. 加速度事件
onEnter函数中
auto accListener = EventListenerAcceleration::create([](Acceleration* acc, Event* event) {
log("onAcceleration x=%f,y=%f,z=%f", acc->x, acc->y, acc->z);
});
disp->addEventListenerWithSceneGraphPriority(accListener, this);
资源链接
github传送门