Cocos2dx Widget 按钮透明区域过滤

前端之家收集整理的这篇文章主要介绍了Cocos2dx Widget 按钮透明区域过滤前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

小伟哥 遇到一个命题:

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

让点击也没有效果滴啦。

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

在网络上很多贴代码的。

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

整理后代码如下:

  1. bool CCMenu::CheckAlphaPoint(CCMenuItem* pChild,const CCPoint& point)
  2. {
  3. CCSize winSize = CCDirector::sharedDirector()->getWinSize();
  4. CCNode* selectSprite = ((CCMenuItemSprite*)pChild)->getSelectedImage();
  5. CCRenderTexture *renderer = CCRenderTexture::create(winSize.width,winSize.height);
  6. renderer->begin();
  7. bool visible = selectSprite->isVisible();
  8. if (visible) {
  9. selectSprite->visit();
  10. }
  11. else
  12. {
  13. selectSprite->setVisible(true);
  14. selectSprite->visit();
  15. selectSprite->setVisible(false);
  16. }
  17. GLubyte pixelColors[4];
  18. #if ( CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
  19. glReadPixels(point.x,point.y,1,GL_RGBA,GL_UNSIGNED_BYTE,&pixelColors[0]);
  20. #else
  21. glReadPixels(point.x,GL_ALPHA,&pixelColors[0]);
  22. #endif
  23. int alpha = pixelColors[0];
  24. CCLOG("----alpha %d",alpha);
  25. renderer->end();
  26. if (alpha <= 30)
  27. {
  28. return true;
  29. }
  30. else
  31. {
  32. return false;
  33. }
  34. }

上面代码的确在测试工程上面直接简历个ccsprite 活着 menuitem 是可以执行的。


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

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


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

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

经过了多重推敲与图纸推测。

后来发现了出现问题的根本原因:

  1. CCRenderTexture *renderer 渲染后不能得到位置上面的颜色值 0 00000为什么为0
  1. visit()好不好使?各种疑惑
  1. bool Widget::onTouchBegan(CCTouch *touch,CCEvent *unused_event)
  2. {
  3. _touchStartPos = touch->getLocation();
  4. _hitted = isEnabled()
  5. & isTouchEnabled()
  6. & hitTest(_touchStartPos)
  7. & clippingParentAreaContainPoint(_touchStartPos);
  8. if (!_hitted)
  9. {
  10. return false;
  11. }
  12. // add yww alpha check
  13. if (!AlphaTouchCheck(_touchStartPos))
  14. {
  15. return false;
  16. }
  17. setFocused(true);
  18. Widget* widgetParent = getWidgetParent();
  19. if (widgetParent)
  20. {
  21. widgetParent->checkChildInfo(0,this,_touchStartPos);
  22. }
  23. pushDownEvent();
  24. return !_touchPassedEnabled;
  25. }

上面是按键检测的逻辑。


下面是修改过的代码。原理很简单 在widget 里面ccnode节点 节点位置 相对父节点是0. 所以在visit的时候 位置就从0,0 开始了。

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


  1. // yww get alpha touch event check
  2. bool Button::AlphaTouchCheck(const CCPoint &point)
  3. {
  4. bool isTouchClaimed = false;
  5. if (getAlphaTouchEnable())
  6. {
  7. // check claimed touch arena
  8. CCSize winSize = CCDirector::sharedDirector()->getWinSize();
  9. CCSprite* selectSprite = (CCSprite*)getVirtualRenderer();
  10. CCPoint cutPos = selectSprite->getPosition();
  11. // CCLOG("getAlphaTouchEnable selectSprite X %f,Y %f",cutPos.x,cutPos.y);
  12. // get screen point
  13. CCPoint wordpx = selectSprite->getParent()->convertToWorldSpace(cutPos);
  14. // CCLOG("getAlphaTouchEnable convertToWorldSpace X %f,wordpx.x,wordpx.y);
  15. selectSprite->setPosition(wordpx);
  16. CCRenderTexture *renderer = CCRenderTexture::create(winSize.width,winSize.height);
  17. //selectSprite->addChild(renderer);
  18. renderer->begin();
  19. bool visible = selectSprite->isVisible();
  20. if (visible)
  21. {
  22. selectSprite->visit();
  23. }
  24. else
  25. {
  26. selectSprite->setVisible(true);
  27. selectSprite->visit();
  28. selectSprite->setVisible(false);
  29. }
  30. GLubyte pixelColors[4];
  31. #if ( CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
  32. glReadPixels(point.x,&pixelColors[0]);
  33. #else
  34. glReadPixels(point.x,&pixelColors[0]);
  35. #endif
  36. int alpha = pixelColors[0];
  37. CCLOG("----alpha %d",alpha);
  38. renderer->end();
  39. selectSprite->setPosition(cutPos);
  40. if (alpha <= 20)
  41. {
  42. isTouchClaimed = false;
  43. }
  44. else
  45. {
  46. isTouchClaimed = true;
  47. }
  48. // check claimed touch arena
  49. }
  50. else
  51. {
  52. isTouchClaimed = true;
  53. }
  54. return isTouchClaimed;
  55. }

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

AlphaTouchCheck

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

在lua里面可以提供检测开关 是否对透明纸进行检测咯。

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

猜你在找的Cocos2d-x相关文章