zoukankan      html  css  js  c++  java
  • cocos2d-x 3.0点击响应

    迄今为止,发现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__
     2 #define  __Touchable_Sprite_Test_H__
     3 
     4 #include "cocos2d.h"
     5 USING_NS_CC;
     6 
     7 class TouchableSpriteTest : public Layer
     8 {
     9 public:
    10     CREATE_FUNC(TouchableSpriteTest);
    11     virtual void onEnter() override;
    12     virtual void onExit() override;
    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, 10);
    11     auto sprite1 = Sprite::create( "images/CyanSquare.png" );
    12     sprite1->setPosition( origin + Point( size.width * 0.5, size.height * 0.5) + Point( -80, 80 ) );
    13     containerForSprite1->addChild(sprite1);
    14 
    15     auto sprite2 = Sprite::create("images/MagentaSquare.png");
    16     sprite2->setPosition(origin+Point(size.width/2, size.height/2));
    17     addChild(sprite2, 20);
    18 
    19     auto sprite3 = Sprite::create("images/YellowSquare.png");
    20     sprite3->setPosition(Point(0, 0));
    21     sprite2->addChild(sprite3, 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, 0, s.width, s.height);
    33 
    34         if (rect.containsPoint(locationInNode))
    35         {
    36             log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
    37             target->setOpacity(180);
    38             return true;
    39         }
    40         return false;
    41     };
    42 
    43     listener1->onTouchMoved = [](Touch* touch, Event* event){
    44         auto target = static_cast<Sprite*>(event->getCurrentTarget());
    45         target->setPosition(target->getPosition() + touch->getDelta());
    46     };
    47 
    48     listener1->onTouchEnded = [=](Touch* touch, Event* event){
    49         auto target = static_cast<Sprite*>(event->getCurrentTarget());
    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(0);
    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 ",[&]( Ref* 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", [&](Ref* 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(0, 0));
    83         menu2->setAnchorPoint(Point(0, 0));
    84         this->addChild(menu2);
    85     });
    86     removeAllTouchItem->setFontSizeObj(16);
    87     removeAllTouchItem->setPosition(right + Point(-100, 0));
    88 
    89     auto menu = Menu::create(removeAllTouchItem, nullptr);
    90     menu->setPosition(Point(0, 0));
    91     menu->setAnchorPoint(Point(0, 0));
    92     addChild(menu);
    93 }
    94 
    95 void TouchableSpriteTest::onExit()
    96 {
    97     Layer::onExit();
    98 }

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

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

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

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

  • 相关阅读:
    ajax语法结构
    数据传输编码模式的解析
    choice参数与MTV和MVC
    only和defer与select_related和prefetch_Related(面试重点)
    聚合查询、分组查询、 F与Q查询
    多表查询
    单表查询
    模板的继承和导入
    模板语法的传值和取值
    IOC依赖注入简单实例
  • 原文地址:https://www.cnblogs.com/slysky/p/3824773.html
Copyright © 2011-2022 走看看