cocos2d-x 3.x之触摸事件

Layer类的一个重要作用就是接受输入事件,它封装了触摸输入的处理接口。一般情况下,我们可以通过setTouchEnabled方法来开启或关闭接收触摸输入。事实上并不是只有Layer才支持接收触摸事件,任何一个游戏元素都可以接收事件,只不过Layer提供了现成的支持。

我们只需通过创建一个事件监听器用来实现各种触发后的逻辑,然后添加到事件分发器_eventDispatcher中,所有事件监听器由这个分发器统一管理,即可完成事件响应。

为一个精灵添加触摸事件的四个步骤
1.创建一个精灵
2.创建一个事件监听器(单点触摸或多点触摸)
3.实现各种触发后的逻辑(onTouchBegan,onTouchMoved,onTouchEnded等)
4.将事件监听器添加到事件分发器中

// 1.首先添加一个精灵元素
bool GameScene::init()
{
	sprite = Sprite::create();
	sprite->setPosition(100, 100);
	this->addChild(sprite);
}

void GameScene::addTouchEvent()
{
	// 2.创建一个单点触摸监听器
	auto touchListener = EventListenerTouchOneByOne::create();

	// 3.实现触摸后的逻辑处理,使用lambda表达式实现触摸事件处理的回调函数
	// 触摸开始
	touchListener->onTouchBegan = [](Touch *touch, Event *event)
	{
		// 获取点击的openGL坐标
		auto touchPos = touch->getLocation();

		// 获取触摸事件的相关目标,即玩家飞机
		auto target = static_cast<Sprite *>(event->getCurrentTarget());

		// 获取飞机所在区域
		auto playerPos = target->getPosition();
		auto playerSize = target->getContentSize();
		auto rect = Rect(playerPos.x - playerSize.width/2, playerPos.y - playerSize.height/2, 
			playerSize.width, playerSize.height);

		if(rect.containsPoint(touchPos))
		{
			return true;
		}

		// 返回false会导致后面的onTouchMoved和onTouchEnded不会执行
		return false;
	};

	// 滑动
	touchListener->onTouchMoved = [](Touch *touch, Event *event)
	{
		auto touchPos = touch->getLocation();

		auto target = static_cast<Sprite *>(event->getCurrentTarget());

		target->setPosition(touchPos);
	};

	// 触摸结束
	touchListener->onTouchEnded = [](Touch *touch, Event *event)
	{
		log("touch end");
	};

	/*
	  4.最后将事件监听器添加到事件分发器_eventDispatcher中 _eventDispatcher是Node的属性,通过它管理当前节点(场景、层、精灵等)的所有事件的分发。但它本身是一个单例模式值的引用,在Node的构造函数中,通过Director::getInstance()->getEventDispatcher(); 获取,有了这个属性,就能方便的处理事件。
	*/
	// _eventDispatcher = Director::getInstance()->getEventDispatcher();
	_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, sprite);
	// 为第二个精灵添加触摸监听_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener->clone(), sprite2);
}
 
 
 当再次使用touchListener 的时候,需要使用clone()方法创建一个新的克隆,因为在使用addEventListenerWithSceneGraphPriority或者addEventListenerWithFixedPriority方法时,会对当前使用的事件监听器添加一个已注册的标记,这使得它不能够被添加多次。另外,有一点非常重要,FixedPriority listener添加完之后需要手动remove,而SceneGraphPriority listener是跟Node绑定的,在Node的析构函数中会被移除。具体的示例用法可以参考引擎自带的tests。 
 

我们可以通过以下方法移除一个已经被添加了的监听器。
_eventDispatcher->removeEventListener(touchListener);

也可以使用如下方法,移除当前事件分发器中所有监听器。
_eventDispatcher->removeAllEventListeners();
当使用removeAll的时候,此节点的所有的监听将被移除,推荐使用指定删除的方式。removeAll之后菜单也不能响应。因为它也需要接受触摸事件。

参考
事件分发机制
http://cn.cocos2d-x.org/article/index?type=cocos2d-x&url=/doc/cocos-docs-master/manual/framework/native/v3/event-dispatcher/zh.md


版权声明:本文为博主原创文章,未经博主允许不得转载。

你可能感兴趣的:(touch,触摸,cocos2d-x)