开发者社区> 技术mix呢> 正文

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里面能够提供检測开关 是否对透明纸进行检測咯。

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





本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5368090.html,如需转载请自行联系原作者 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
ViewPager如何区分自动切换和手势滑动切换
ViewPager是一个很常见的组件,不仅支持收拾滑动切换页面,我们还可以通过`viewPager.setCurrentItem(index)`来切换到指定的页面,那么他们如何区分呢? 我们知道ViewPager可以添加`ViewPager.OnPageChangeListener`监听器,可以监听切换的状态。通过观察`ViewPager.OnPageChangeListener#onPageScrollStateChanged(int state)`方法中state的输出,发现了手势切换和自动切换的规律。
53 0
Android控件显示、隐藏时,增加动画效果
Android控件显示、隐藏时,增加动画效果
297 0
01day 动态绑定变量 导航组件 view text是否可以复制 button 上下滚动组件
01day 动态绑定变量 导航组件 view text是否可以复制 button 上下滚动组件
43 0
PyQt5 技术篇-QWidget、Dialog设置界面固定大小、不可拉伸方法实例演示
PyQt5 技术篇-QWidget、Dialog设置界面固定大小、不可拉伸方法实例演示
446 0
Android ListView的每个子Item如何设置高度
Android ListView的每个子Item如何设置高度
375 0
tablayout支持改变选中文字大小,支持左右滑动,支持viewpager,支持三角可移动指示器
TabLayout [简书地址] (https://www.jianshu.com/p/2c3f868266e8) 基于大神的FlycoTabLayout 传送地址和基本用法 用法和属性和这个库一样 效果图如下 Gif_20180828_142709.
2340 0
Android NestedScrollView滚动到顶部固定子View悬停挂靠粘在顶端
Android NestedScrollView滚动到顶部固定子View悬停挂靠粘在顶端 网上有一个StickyScrollView,称之为粘性ScrollView,比如一个垂直方向的布局,依次摆放几个子View,当某一个子View滚到到顶端时候要停靠在顶部,悬停在顶部的位置不动。
2602 0
Android扩大点击事件接收区域范围
Android扩大点击事件接收区域范围 如果有些icon或者ImageView,这些View本身很小,就扩大这些事件的接收区域。
2009 0
Android代码设置TextView的顶部图及设置图与字体之间距离
终于建了一个自己个人小站:https://huangtianyu.gitee.io,以后优先更新小站博客,欢迎进站,O(∩_∩)O~~ 现在很多的设计底部都是几个Tab标签,每个标签都是上边是图片,下边是文字。
2244 0
android ListView包含Checkbox滑动时状态改变
题外话: 在xamarin android的开发中基本上所有人都会遇到这个小小的坎,的确有点麻烦,当时我也折腾了好一半天,如果你能看到这篇博客,说明你和我当初也是一样的焦灼,如果你想解决掉这个小小的坎,那么不要着急,一步一步来。
889 0
+关注
技术mix呢
文章
问答
视频
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载