想要使用新的触控机制,最好先要了解一下,lambda表达式。
C++ 11引入了lambda表达式,所以Cocos2d-x3.0也应用了lambda表达式。
由于Lambda的类型是唯一的,不能通过类型名来显式声明对应的对象,但可以利用auto关键字和类型推导:
auto f = [](int a, int b){return a > b;};
比如,
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));
void HelloWorld::menuCloseCallback(Object* sender)
{
Director::getInstance()->end();
}
使用了lambda后
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
[](Object* sender)
{
Director::getInstance()->end();//直接在这里添加按钮要调用的代码
});
引用: Lambda
首先创建三个Sprite
//Create a "one by one" touch event listener (processes one touch at a time)
auto listener1 = EventListenerTouchOneByOne::create();
// When "swallow touches" is true, then returning 'true' from the onTouchBegan method will "swallow" the touch event, preventing other listeners from using it.
listener1->setSwallowTouches(true);
// Example of using a lambda expression to implement onTouchBegan event callback function
listener1->onTouchBegan = [](Touch* touch, Event* event){
// event->getCurrentTarget() returns the *listener's* sceneGraphPriority node.
auto target = static_cast(event->getCurrentTarget());
//Get the position of the current point relative to the button
Point locationInNode = target->convertToNodeSpace(touch->getLocation());
Size s = target->getContentSize();
Rect rect = Rect(0, 0, s.width, s.height);
//Check the click area
if (rect.containsPoint(locationInNode))
{
log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
target->setOpacity(180);
return true;
}
return false;
};
//Trigger when moving touch
listener1->onTouchMoved = [](Touch* touch, Event* event){
auto target = static_cast(event->getCurrentTarget());
//Move the position of current button sprite
target->setPosition(target->getPosition() + touch->getDelta());
};
//Process the touch end event
listener1->onTouchEnded = [=](Touch* touch, Event* event){
auto target = static_cast(event->getCurrentTarget());
log("sprite onTouchesEnded.. ");
target->setOpacity(255);
//Reset zOrder and the display sequence will change
if (target == sprite2)
{
sprite1->setZOrder(100);
}
else if(target == sprite1)
{
sprite1->setZOrder(0);
}
};
//Add listener
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3);
新的触碰制
乍看之下新的事件处理机制好像比2.x版本的事件机制更加繁琐。但是在旧版本中,当你继承了一个被代理的类,例如一个定义了onTouchBegan()方法的类,那你的事件处理将会进入这些被代理的方法里。
新的事件机制移除掉了代理的事件处理逻辑,将事件处理封装到监听器里,通过以下步骤来实现监听逻辑:如果你不喜欢这个方法,那么还有另一个方法供你选择
// 创建一个事件监听器 OneByOne 为单点触摸
auto listener1 = EventListenerTouchOneByOne::create();
//设置是否吞没事件,在 onTouchBegan 方法返回 true 时吞没
//当设置为true时,在 onTouchBegan 中会执行相应的判断,以决定其返回值是 false 还是 true,
//用来处理触摸事件是否依据显示的顺序关系向后传递。
listener1->setSwallowTouches(true);
//在这里明确的定义出了开始触摸的函数
listener1->onTouchBegan = CC_CALLBACK_2(EventManager::onTouchBegan, this);
listener1->onTouchEnded = CC_CALLBACK_2(EventManager::onTouchEnded, this);
listener1->onTouchMoved = CC_CALLBACK_2(EventManager::onTouchMoved, this);
//CC_CALLBACK说明
//CC_CALLBACK_0 0个参数
//CC_CALLBACK_1 1个参数
//CC_CALLBACK_2 2个参数
//.................
// 添加监听器
//有一点非常重要,FixedPriority listener添加完之后需要手动remove,
//而SceneGraphPriority listener是跟node绑定的,在node的析构函数中会被移除
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3);
这个和上一段作用是相同的,不过这个比较自定义一点,上边的一段明显比较官方一点,大家用哪个,都是可以的。但是,比如
bool EventManager::onTouchBegan(Touch* touch, Event* event)
这些东西,是需要在.h文件定义的。
最后说明下**********************这篇文章为1年前所编辑,所以只时发布了出去,不会提供任何维护,而且,东西也挺简单的大家看看就算了