cocos2dx 事件處理機制、觸摸事件、鍵盤事件、鼠標事件、Lambda表達式


事件處理

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章