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传送门

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