小伟哥 遇到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里面可以提供检测开关 是不是对透明纸进行检测咯。
不多往下说了。浪费网络内存咯。