zoukankan      html  css  js  c++  java
  • Cocos2dx Widget button透明区域过滤

    小伟哥 遇到一个命题:

    button透明区域过滤。当点击一个建筑button、花的时候不得不想一些方法把点击透明区域过滤掉。

    让点击也没有效果滴啦。

    開始搜索了半天才有所思路。

    在网络上非常多贴代码的。

    http://blog.csdn.net/lwuit/article/details/40658347

    整理后代码例如以下:

    bool CCMenu::CheckAlphaPoint(CCMenuItem* pChild, const CCPoint& point)
    {
        CCSize winSize = CCDirector::sharedDirector()->getWinSize();
        CCNode* selectSprite = ((CCMenuItemSprite*)pChild)->getSelectedImage();
        
        CCRenderTexture *renderer = CCRenderTexture::create(winSize.width, winSize.height);
        renderer->begin();
        
        bool visible = selectSprite->isVisible();
        if (visible) {
            selectSprite->visit();
        }
        else
        {
            selectSprite->setVisible(true);
            selectSprite->visit();
            selectSprite->setVisible(false);
        }
        
        GLubyte pixelColors[4];
        
    #if ( CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
        glReadPixels(point.x, point.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixelColors[0]);
    #else
        glReadPixels(point.x, point.y, 1, 1, GL_ALPHA, GL_UNSIGNED_BYTE, &pixelColors[0]);
    #endif
        
        int alpha = pixelColors[0];
        CCLOG("----alpha %d", alpha);
        
        renderer->end();
        
        if (alpha <= 30)
        {
           return true;
        }
        else
        {
            return false;
        }
        
    }

    上面代码的确在測试project上面直接简历个ccsprite 活着 menuitem 是能够运行的。


    随着UI工具的进步。我们选择了CocoStudio 的 Widget 。方便了你我啊。

    可是可可是,把上面的代码贴过来,试了试真心不能用啊。


    有些同志,到此放弃了对知识原理的探究。 

    程序就是苦啊。遇到这种问题必须往下研究不是? 

    经过了多重推敲与图纸猜測。

    后来发现了出现故障的根本原因:

    CCRenderTexture *renderer 渲染后不能得到位置上面的颜色值 为0 00000为什么为0 
    visit()好不好使?各种疑惑

    bool Widget::onTouchBegan(CCTouch *touch, CCEvent *unused_event)
    {
        _touchStartPos = touch->getLocation();
        _hitted = isEnabled()
                & isTouchEnabled()
                & hitTest(_touchStartPos)
        & clippingParentAreaContainPoint(_touchStartPos);
        
        if (!_hitted)
        {
            return false;
        }
        
        // add yww alpha check
        if (!AlphaTouchCheck(_touchStartPos))
        {
            return false;
        }
        
        setFocused(true);
        Widget* widgetParent = getWidgetParent();
        if (widgetParent)
        {
            widgetParent->checkChildInfo(0,this,_touchStartPos);
        }
        pushDownEvent();
        return !_touchPassedEnabled;
    }

    上面是按键检測的逻辑。


    以下是改动过的代码。原理非常easy  在widget 里面ccnode节点 节点位置 相对父节点是0. 所以在visit的时候 位置就从0。0 開始了。

    我们矫正下改渲染节点的位置。转成屏幕坐标 然后在依据touch 坐标获取当前点击像素的 透明值。


    // yww get alpha touch event check
    bool Button::AlphaTouchCheck(const CCPoint &point)
    {
        bool isTouchClaimed = false;
        
        if (getAlphaTouchEnable())
        {
                // check claimed touch arena
                CCSize winSize = CCDirector::sharedDirector()->getWinSize();
                CCSprite* selectSprite = (CCSprite*)getVirtualRenderer();
                CCPoint cutPos = selectSprite->getPosition();
                // CCLOG("getAlphaTouchEnable selectSprite X %f, Y %f", cutPos.x, cutPos.y);
            
                // get screen point
                CCPoint wordpx = selectSprite->getParent()->convertToWorldSpace(cutPos);
                // CCLOG("getAlphaTouchEnable convertToWorldSpace X %f, Y %f", wordpx.x, wordpx.y);
            
                selectSprite->setPosition(wordpx);
            
                CCRenderTexture *renderer = CCRenderTexture::create(winSize.width, winSize.height);
                //selectSprite->addChild(renderer);
            
                renderer->begin();
            
                bool visible = selectSprite->isVisible();
                if (visible)
                {
                    selectSprite->visit();
                }
                else
                {
                    selectSprite->setVisible(true);
                    selectSprite->visit();
                    selectSprite->setVisible(false);
                }
            
                GLubyte pixelColors[4];
            
    #if ( CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
                glReadPixels(point.x, point.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixelColors[0]);
    #else
                glReadPixels(point.x, point.y, 1, 1, GL_ALPHA, GL_UNSIGNED_BYTE, &pixelColors[0]);
    #endif
            
                int alpha = pixelColors[0];
                CCLOG("----alpha %d", alpha);
            
                renderer->end();
            
                selectSprite->setPosition(cutPos);
            
                if (alpha <= 20)
                {
                    isTouchClaimed = false;
                }
                else
                {
                    isTouchClaimed = true;
                }
            // check claimed touch arena
        }
        else
        {
            isTouchClaimed = true;
        }
        return isTouchClaimed;
    }
    

    上面逻辑是 重写了widget 的自己定义函数

    AlphaTouchCheck

    这个依据自己的需求构建结构了。

    在lua里面能够提供检測开关 是否对透明纸进行检測咯。

    不多往下说了。浪费网络内存咯。


  • 相关阅读:
    使用线程新建WPF窗体(公用进度条窗体)
    WPF--模板选择
    WPF命令(Command)介绍、命令和数据绑定集成应用
    WPF 员工卡条形码
    WPF入门教程系列(二) 深入剖析WPF Binding的使用方法
    R语言——实验5-聚类分析
    R语言——实验5-聚类分析
    Java学习---流与文件
    Java学习---流与文件
    Java学习---异常处理
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5368090.html
Copyright © 2011-2022 走看看