Cocos2dx Widget 按鈕透明區域過濾
來源:程序員人生 發布時間:2014-11-07 08:36:56 閱讀次數:3137次
小偉哥 遇到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里面可以提供檢測開關 是不是對透明紙進行檢測咯。
不多往下說了。浪費網絡內存咯。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈