迄今为止,发现cocos2d-x 3.0最让人惊艳的地方就是更改了点击事件机制。(ps:迄今只看了点击事件这块,捂嘴笑~~~)

cocos2d-x 2.0 只有CCLayer有点击事件处理,需要注册,需要实现onTouchBegan等方法,最坑爹的就是按照优先级来传递点击事件,让人诟病不已。每次遇到由于优先级而造成的点击bug,都有一种崩溃之感。

让人高兴的是,从现在开始,这种情况应该就会很少遇到了。闲话不说,开始正文。

3.0版本中,处理点击事件有两种方式:

1、函数回调

函数回调是最简单的响应形式,一直以来被用于MenuItem中的点击处理。在新版本中,此处发生了些小改变,也就是采用了CC_CALLBACK系列,有不明白的可以去看帖子:c++11特性与cocos2d-x 3.0之std::bind与std::function

 // a selector callback
void menuCloseCallback(Object* pSender); auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); void HelloWorld::menuCloseCallback(Object* pSender)
{
Director::getInstance()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit();
#endif
}

其中CC_CALLBACK_1宏是将函数与对象绑定在一起,1表示这个函数有一个参数。当点击这个按钮时,会调用这个回调函数。

除了基于c++11的这个形式的改变,使用方法与先前相同。

2、Listener消息响应方式

Listener的加入,使得Sprite可以很方便的就可以拥有处理点击事件的能力。再也不用为了写个能够响应事件的Sprite而让去继承Layer了。总觉得class TestSprite : public CCLayer这种定义Sprite的方式是坑人的一种做法。终于可以将其摒弃了。

3.0版本,只需要为Sprite创建一个Listener,然后将Listener与Sprite绑定,并添加到Listener队列内即可,方便至极。

另,每一个Listener也只能和一个Sprite进行绑定,而Listener的clone方法,可以很方便的将listener复制为其他对象可用的listener。

废话少说,上代码最重要:

 #ifndef  __Touchable_Sprite_Test_H__
#define __Touchable_Sprite_Test_H__ #include "cocos2d.h"
USING_NS_CC; class TouchableSpriteTest : public Layer
{
public:
CREATE_FUNC(TouchableSpriteTest);
virtual void onEnter() override;
virtual void onExit() override;
}; #endif
 #include "TouchableSpriteTest.h"

 void TouchableSpriteTest::onEnter()
{
Layer::onEnter();
Point origin = Director::getInstance()->getVisibleOrigin();
Size size = Director::getInstance()->getVisibleSize(); auto containerForSprite1 = Node::create();
this->addChild(containerForSprite1, );
auto sprite1 = Sprite::create( "images/CyanSquare.png" );
sprite1->setPosition( origin + Point( size.width * 0.5, size.height * 0.5) + Point( -, ) );
containerForSprite1->addChild(sprite1); auto sprite2 = Sprite::create("images/MagentaSquare.png");
sprite2->setPosition(origin+Point(size.width/, size.height/));
addChild(sprite2, ); auto sprite3 = Sprite::create("images/YellowSquare.png");
sprite3->setPosition(Point(, ));
sprite2->addChild(sprite3, );
// Make sprite1 touchable
auto listener1 = EventListenerTouchOneByOne::create(); listener1->setSwallowTouches(true); listener1->onTouchBegan = [](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget()); Point locationInNode = target->convertToNodeSpace(touch->getLocation());
Size s = target->getContentSize();
Rect rect = Rect(, , s.width, s.height); if (rect.containsPoint(locationInNode))
{
log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
target->setOpacity();
return true;
}
return false;
}; listener1->onTouchMoved = [](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
target->setPosition(target->getPosition() + touch->getDelta());
}; listener1->onTouchEnded = [=](Touch* touch, Event* event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
log("sprite onTouchesEnded.. ");
target->setOpacity();
if (target == sprite2)
{
containerForSprite1->setLocalZOrder();
}
else if(target == sprite1)
{
containerForSprite1->setLocalZOrder();
}
}; _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3); Rect s_visibleRect = Director::getInstance()->getOpenGLView()->getVisibleRect();
Point right = Point(s_visibleRect.origin.x+s_visibleRect.size.width, s_visibleRect.origin.y+s_visibleRect.size.height/); auto removeAllTouchItem = MenuItemFont::create("Remove All Touch Listeners ",[&]( Ref* sender ){
auto senderItem = static_cast<MenuItemFont*>(sender);
senderItem->setString("Only next item could be clicked "); _eventDispatcher->removeEventListenersForType( EventListener::Type::TOUCH_ONE_BY_ONE ); auto nextItem = MenuItemFont::create("Next", [&](Ref* sender){
}); nextItem->setFontSizeObj();
nextItem->setPosition(right + Point(-, -)); auto menu2 = Menu::create(nextItem, NULL);
menu2->setPosition(Point(, ));
menu2->setAnchorPoint(Point(, ));
this->addChild(menu2);
});
removeAllTouchItem->setFontSizeObj();
removeAllTouchItem->setPosition(right + Point(-, )); auto menu = Menu::create(removeAllTouchItem, nullptr);
menu->setPosition(Point(, ));
menu->setAnchorPoint(Point(, ));
addChild(menu);
} void TouchableSpriteTest::onExit()
{
Layer::onExit();
}

千里之行始于足下,一切才刚刚开始,想要理解cocos2dx 3.0的点击事件,还是需要深入理解其底层实现的。

大家可以去看  Cocos2d-X3.0 刨根问底(七)----- 事件机制Event源码分析   这应该是一篇好文。

另,本博文参考自:http://blog.csdn.net/fansongy/article/details/12716671

本博主对一切都将不负任何法律责任。

cocos2d-x 3.0点击响应的更多相关文章

  1. 高屋建瓴 cocos2d-x-3.0架构设计 Cocos2d (v.3.0) rendering pipeline roadmap(原文)

    Cocos2d (v.3.0) rendering pipeline roadmap Why (the vision) The way currently Cocos2d does rendering ...

  2. ThinkPHP5.0框架开发--第6章 TP5.0 请求和响应

    ThinkPHP5.0框架开发--第6章 TP5.0 请求和响应 第6章 TP5.0 请求和响应 ===================================== 上次复习 1.新建控制器 ...

  3. 2019-11-29-WPF-非客户区的触摸和鼠标点击响应

    原文:2019-11-29-WPF-非客户区的触摸和鼠标点击响应 title author date CreateTime categories WPF 非客户区的触摸和鼠标点击响应 lindexi ...

  4. 2019-8-8-WPF-非客户区的触摸和鼠标点击响应

    title author date CreateTime categories WPF 非客户区的触摸和鼠标点击响应 lindexi 2019-08-08 16:48:31 +0800 2019-07 ...

  5. vue2.0点击其他任何地方隐藏dom

    methods: { handleBodyClick(){ if (绿色区域出来了,要判断点击其他地方就要关闭,这样可以避免绿色区域已经关闭还在操作) { let _con = $(目标区域) if ...

  6. UGUI实现不规则区域点击响应

    UGUI实现不规则区域点击响应 前言 大家吼啊!最近工作上事情特别多,没怎么打理博客.今天无意打开cnblog才想起该写点东西了.今天给大家讲一个Unity中不规则区域点击响应的实现方法,使用UGUI ...

  7. 浅谈ClickableSpan , 实现TextView文本某一部分文字的点击响应

    超文本:http://www.baidu.com 这么一个效果:一行文本当中 前面显示黑色颜色的“超文本:”,后面显示红色颜色的“http://www.baidu.com” 并且要求红色字体的部分可以 ...

  8. Vue.2.0.5-深入响应式原理

    大部分的基础内容我们已经讲到了,现在讲点底层内容.Vue 最显著的一个功能是响应系统 -- 模型只是普通对象,修改它则更新视图.这会让状态管理变得非常简单且直观,不过理解它的原理以避免一些常见的陷阱也 ...

  9. Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(八)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 回到Xcode中,新建一个EndLayer类,继承于CCNode ...

随机推荐

  1. 【剑指offer】二分查找二维数组

    1 2 3 4 5 6 7 8 9 3 3 1 2 3 4 5 6 7 8 9 10 3 3 12 2 3 4 5 6 7 8 9 10 例子输出: Yes No No 时间限制:1 秒 内存限制:3 ...

  2. yml 配置文件注入

    配置文件 JavaBean 自动提示 测试

  3. git检查与放弃本地的代码修改情况

    git diff  可以查看当前没有add 的内容修改(不在缓冲区的文件变化) git diff --cached查看已经add但没有commit 的改动(在缓冲区的文件变化) git diff HE ...

  4. java 泛型 精析

      Created by Marydon on 1.概述 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数: 这种参数类型可以用在类.接口和方法的 ...

  5. ORA-27090 故障一例

    近期的alert日志中碰到了ORA-27090的错误信息.其错误提示为Unable to reserve kernel resources for asynchronous disk I/O.依据这个 ...

  6. JUC-闭锁:CountDownLatch

    CountDownLatch::闭锁,在完成某些运算是,只有其他所有线程的运算全部完成,当前运算才继续执行. 实例化:参数:设置一个计数器的值. final CountDownLatch latch ...

  7. Log4net的配置-按照日期+文件大小混合分割

    ender name="DebugAppender" type="log4net.Appender.RollingFileAppender"><fi ...

  8. 修改Cygwin的默认启动路径

    原先启动Cygwin后,pwd显示: C:\Documents and Settings\Administrator@IBM-EBDC0EAC4B7 ~$ pwdC:\Documents and Se ...

  9. 更改npm全局模块和cache默认安装位置

    来源于:http://blog.csdn.net/friendan/article/details/51736231 1.因为我安装的Node.js自带了npm,所以在nodejs文件夹里面新建以下两 ...

  10. 概率校准Probability Calibration

    在分类问题中,我们有时不仅仅需要给测试样本打上类别标签,也需要给出一个"置信度"来表示该样本属于此类别的可能性. 然而,有的分类器只能直接打上类别标签没法给出置信度.概率校准就是用 ...