zoukankan      html  css  js  c++  java
  • cocos 新手引导之事件穿透

    游戏中新手引导 一般都是通过蒙版然后突出某一位置,并配合相应动画来实现的。遮罩层有两个需求,一是可以挖个洞,二是这个洞事件可以穿透,

    其他区域不能穿透。如果事件不能穿透,那就需要做很多工作来处理相应的响应。穿透之后实际点的就是那个位置,只需要处理遮罩部分应该有的行为

    研究了cocos2dx 3.1 的事件系统,发现虽然不能原生支持,但我们可以简单扩展一下就能达到我们的目的

    下边是源代码:

    LayoutTouchBreak.h

    class LayoutTouchBreak: public Layout
    {
        DECLARE_CLASS_GUI_INFO
    
    public:
        LayoutTouchBreak();
        LayoutTouchBreak(Layout* widget);
    
        static LayoutTouchBreak* create();
        static LayoutTouchBreak* createWithLayout( Layout* widget );
    
    
        ~LayoutTouchBreak();
    
        void setBreakArea( Rect& rect );
    
    CC_CONSTRUCTOR_ACCESS:
        virtual bool init() override;
    
    protected:
        virtual bool onTouchBegan(Touch *touch, Event *unusedEvent) override;
        virtual void onTouchMoved(Touch *touch, Event *unusedEvent) override;
        virtual void onTouchEnded(Touch *touch, Event *unusedEvent) override;
        virtual void onTouchCancelled(Touch *touch, Event *unusedEvent) override;
    
        virtual Widget* createCloneInstance() override;
    private:
    
        //触摸是否在穿透区域内
        bool touchInBreakArea(Touch *touch);
    
        // 触摸事件如果在这个矩形区域内,则可以穿透 继续传递下去
        Rect _breakArea;
    };

    LayoutTouchBreak.cpp

    IMPLEMENT_CLASS_GUI_INFO(LayoutTouchBreak)
    
    LayoutTouchBreak::LayoutTouchBreak()
    {
    
    }
    
    LayoutTouchBreak::LayoutTouchBreak(Layout* widget)
    {
        copySpecialProperties(widget);
    }
    
    LayoutTouchBreak::~LayoutTouchBreak()
    {
    
    }
    
    LayoutTouchBreak* LayoutTouchBreak::create()
    {
        LayoutTouchBreak* layoutTouchBreak = new LayoutTouchBreak();
        if (layoutTouchBreak && layoutTouchBreak->init())
        {
            layoutTouchBreak->autorelease();
            return layoutTouchBreak;
        }
        CC_SAFE_DELETE(layoutTouchBreak);
        return nullptr;
    }
    
    LayoutTouchBreak* LayoutTouchBreak::createWithLayout( Layout* widget )
    {
        if (widget == nullptr)
        {
            return nullptr;
        }
    
        LayoutTouchBreak* l = create();
        if (l)
        {
            l->copyProperties(widget);
            l->copySpecialProperties(widget);
        }
        return l;
    }
    
    Widget* LayoutTouchBreak::createCloneInstance()
    {
        return LayoutTouchBreak::create();
    }
    
    
    void LayoutTouchBreak::setBreakArea(Rect& rect)
    {
        _breakArea = rect;
    }
    
    bool LayoutTouchBreak::onTouchBegan(Touch *touch, Event *unusedEvent)
    {
        bool hitted = Layout::onTouchBegan(touch, unusedEvent);
        if (touchInBreakArea(touch))
        {
            _touchListener->setSwallowTouches(false);
        }
        else
        {
            _touchListener->setSwallowTouches(true);
        }
        return hitted;
    }
    
    void LayoutTouchBreak::onTouchMoved(Touch *touch, Event *unusedEvent)
    {
        Layout::onTouchMoved(touch, unusedEvent);
        if (touchInBreakArea(touch))
        {
            _touchListener->setSwallowTouches(false);
        }
        else
        {
            _touchListener->setSwallowTouches(true);
        }
        
    }
    
    void LayoutTouchBreak::onTouchEnded(Touch *touch, Event *unusedEvent)
    {
        Layout::onTouchEnded(touch, unusedEvent);
        if (touchInBreakArea(touch))
        {
            _touchListener->setSwallowTouches(false);
        }
        else
        {
            _touchListener->setSwallowTouches(true);
        }
    }
    
    void LayoutTouchBreak::onTouchCancelled(Touch *touch, Event *unusedEvent)
    {
        Layout::onTouchCancelled(touch, unusedEvent);
        if (touchInBreakArea(touch))
        {
            _touchListener->setSwallowTouches(false);
        }
        else
        {
            _touchListener->setSwallowTouches(true);
        }
    }
    
    bool LayoutTouchBreak::init()
    {
        return Layout::init();
    }
    
    bool LayoutTouchBreak::touchInBreakArea(Touch *touch)
    {
        auto touchPos = touch->getLocation();
        Vec2 nsp = convertToNodeSpace(touchPos);
        if (_breakArea.containsPoint(nsp))
        {
            return true;
        }
        return false;
    }

    只要动态的根据 touch 的位置决定是否 吞并事件就好了

  • 相关阅读:
    ComboBox
    EntityFramework之领域驱动设计实践(九)(转)
    EntityFramework之领域驱动设计实践(八)(转)
    Rectangle Button
    Silverlight 4中拖拽效果实现附源码下载
    Silverlight RIA Services Class Library类库使用1.
    如何添加/删除一个RIA Service Link
    Silverlight开发技巧总结实时更新
    Silverlight 4中把DataGrid数据导出Excel—附源码下载
    Silverlight4不同控件间拖拽实现附源码下载
  • 原文地址:https://www.cnblogs.com/dou-ya/p/4290745.html
Copyright © 2011-2022 走看看