程序员人生 网站导航

Cocos2dx Widget 按钮透明区域过滤

栏目:互联网时间:2014-11-07 08:36:56

小伟哥 遇到1个命题:

按钮透明区域过滤。当点击1个建筑按钮、花的时候不能不想1些方法把点击透明区域过滤掉。

让点击也没有效果滴啦。

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

在网络上很多贴代码的。

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; } }

上面代码的确在测试工程上面直接简历个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; }

上面是按键检测的逻辑。


下面是修改过的代码。原理很简单  在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里面可以提供检测开关 是不是对透明纸进行检测咯。

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


------分隔线----------------------------
------分隔线----------------------------

最新技术推荐