目錄
事件處理
- 事件源:場景中的對象,每個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傳送門