cocos2d-x 3.0点击响应
转自:http://www.cnblogs.com/slysky/p/3824773.html 参考:http://cn.cocos2d-x.org/tutorial/show?id=231
迄今为止,发现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
1 // a selector callback 2 void menuCloseCallback(Object* pSender); 3 4 auto closeItem = MenuItemImage::create("CloseNormal.png",CloseSelected.png", 5 CC_CALLBACK_1(HelloWorld::menuCloseCallback,this)); 6 7 void HelloWorld::menuCloseCallback(Object* pSender) 8 { 9 Director::getInstance()->end(); 10 11 #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 12 exit(0); 13 #endif 14 } 其中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。 废话少说,上代码最重要: 1 #ifndef __Touchable_Sprite_Test_H__
#define __Touchable_Sprite_Test_H__
4 #include cocos2d.h"
5 USING_NS_CC;
class TouchableSpriteTest : public Layer
9 public:
10 CREATE_FUNC(TouchableSpriteTest);
11 virtual void onEnter() override;
12 void onExit() 13 };
14
15 #endif
1 #include TouchableSpriteTest.h 2
3 void TouchableSpriteTest::onEnter()
4 {
5 Layer::onEnter();
6 Point origin = Director::getInstance()->getVisibleOrigin();
7 Size size = Director::getInstance()->getVisibleSize();
8
9 auto containerForSprite1 = Node::create();
10 this->addChild(containerForSprite1,128); line-height:1.5!important">10);
11 auto sprite1 = Sprite::create( images/CyanSquare.png" );
12 sprite1->setPosition( origin + Point( size.width * 0.5,size.height * 0.5) + Point( -80,128); line-height:1.5!important">80 ) );
13 containerForSprite1->addChild(sprite1);
15 auto sprite2 = Sprite::create(images/MagentaSquare.png");
16 sprite2->setPosition(origin+Point(size.width/2,size.height/2));
17 addChild(sprite2,128); line-height:1.5!important">20);
18
19 auto sprite3 = Sprite::create(images/YellowSquare.png20 sprite3->setPosition(Point(0,128); line-height:1.5!important">0));
21 sprite2->addChild(sprite3,128); line-height:1.5!important">1);
22 Make sprite1 touchable
23 auto listener1 = EventListenerTouchOneByOne::create();
24
25 listener1->setSwallowTouches(true);
26
27 listener1->onTouchBegan = [](Touch* touch,Event* event){
28 auto target = static_cast<Sprite*>(event->getCurrentTarget());
29
30 Point locationInNode = target->convertToNodeSpace(touch->getLocation());
31 Size s = target->getContentSize();
32 Rect rect = Rect(0,s.width,s.height);
33
34 if (rect.containsPoint(locationInNode))
35 {
36 log(sprite began... x = %f,y = %f37 target->setOpacity(180);
38 return true;
39 }
40 false;
41 };
42
43 listener1->onTouchMoved = [](Touch* touch,128); line-height:1.5!important">44 auto target = static_cast<Sprite*>(45 target->setPosition(target->getPosition() + touch->getDelta());
46 };
47
48 listener1->onTouchEnded = [=](Touch* touch,128); line-height:1.5!important">49 auto target = static_cast<Sprite*>(50 log(sprite onTouchesEnded.. 51 target->setOpacity(255);
52 if (target == sprite2)
53 {
54 containerForSprite1->setLocalZOrder(100);
55 }
56 else if(target == sprite1)
57 {
58 containerForSprite1->setLocalZOrder(59 }
60 };
61
62 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1,sprite1);
63 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(),sprite2);
64 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(),sprite3);
65
66 Rect s_visibleRect = Director::getInstance()->getOpenGLView()->getVisibleRect();
67 Point right = Point(s_visibleRect.origin.x+s_visibleRect.size.width,s_visibleRect.origin.y+s_visibleRect.size.height/2);
68
69 auto removeAllTouchItem = MenuItemFont::create(Remove All Touch Listeners sender ){
70 auto senderItem = static_cast<MenuItemFont*>(sender);
71 senderItem->setString(Only next item could be clicked 72
73 _eventDispatcher->removeEventListenersForType( EventListener::Type::TOUCH_ONE_BY_ONE );
74
75 auto nextItem = MenuItemFont::create(Next sender){
76 });
77
78 nextItem->setFontSizeObj(16);
79 nextItem->setPosition(right + Point(-100,-30));
80
81 auto menu2 = Menu::create(nextItem,NULL);
82 menu2->setPosition(Point(83 menu2->setAnchorPoint(Point(84 this->addChild(menu2);
85 });
86 removeAllTouchItem->setFontSizeObj(87 removeAllTouchItem->setPosition(right + Point(-88
89 auto menu = Menu::create(removeAllTouchItem,nullptr);
90 menu->setPosition(Point(91 menu->setAnchorPoint(Point(92 addChild(menu);
93 }
94
95 void TouchableSpriteTest::onExit()
96 {
97 Layer::onExit();
98 }
千里之行始于足下,一切才刚刚开始,想要理解cocos2dx 3.0的点击事件,还是需要深入理解其底层实现的。 大家可以去看 Cocos2d-X3.0 刨根问底(七)----- 事件机制Event源码分析 这应该是一篇好文。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |