小伟哥 遇到一个命题:

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

让点击也没有效果滴啦。

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

在网络上非常多贴代码的。

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.  
  6. CCRenderTexture *renderer = CCRenderTexture::create(winSize.width, winSize.height);
  7. renderer->begin();
  8.  
  9. bool visible = selectSprite->isVisible();
  10. if (visible) {
  11. selectSprite->visit();
  12. }
  13. else
  14. {
  15. selectSprite->setVisible(true);
  16. selectSprite->visit();
  17. selectSprite->setVisible(false);
  18. }
  19.  
  20. GLubyte pixelColors[4];
  21.  
  22. #if ( CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
  23. glReadPixels(point.x, point.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixelColors[0]);
  24. #else
  25. glReadPixels(point.x, point.y, 1, 1, GL_ALPHA, GL_UNSIGNED_BYTE, &pixelColors[0]);
  26. #endif
  27.  
  28. int alpha = pixelColors[0];
  29. CCLOG("----alpha %d", alpha);
  30.  
  31. renderer->end();
  32.  
  33. if (alpha <= 30)
  34. {
  35. return true;
  36. }
  37. else
  38. {
  39. return false;
  40. }
  41.  
  42. }

上面代码的确在測试project上面直接简历个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.  
  9. if (!_hitted)
  10. {
  11. return false;
  12. }
  13.  
  14. // add yww alpha check
  15. if (!AlphaTouchCheck(_touchStartPos))
  16. {
  17. return false;
  18. }
  19.  
  20. setFocused(true);
  21. Widget* widgetParent = getWidgetParent();
  22. if (widgetParent)
  23. {
  24. widgetParent->checkChildInfo(0,this,_touchStartPos);
  25. }
  26. pushDownEvent();
  27. return !_touchPassedEnabled;
  28. }

上面是按键检測的逻辑。

以下是改动过的代码。原理非常easy  在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.  
  6. if (getAlphaTouchEnable())
  7. {
  8. // check claimed touch arena
  9. CCSize winSize = CCDirector::sharedDirector()->getWinSize();
  10. CCSprite* selectSprite = (CCSprite*)getVirtualRenderer();
  11. CCPoint cutPos = selectSprite->getPosition();
  12. // CCLOG("getAlphaTouchEnable selectSprite X %f, Y %f", cutPos.x, cutPos.y);
  13.  
  14. // get screen point
  15. CCPoint wordpx = selectSprite->getParent()->convertToWorldSpace(cutPos);
  16. // CCLOG("getAlphaTouchEnable convertToWorldSpace X %f, Y %f", wordpx.x, wordpx.y);
  17.  
  18. selectSprite->setPosition(wordpx);
  19.  
  20. CCRenderTexture *renderer = CCRenderTexture::create(winSize.width, winSize.height);
  21. //selectSprite->addChild(renderer);
  22.  
  23. renderer->begin();
  24.  
  25. bool visible = selectSprite->isVisible();
  26. if (visible)
  27. {
  28. selectSprite->visit();
  29. }
  30. else
  31. {
  32. selectSprite->setVisible(true);
  33. selectSprite->visit();
  34. selectSprite->setVisible(false);
  35. }
  36.  
  37. GLubyte pixelColors[4];
  38.  
  39. #if ( CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
  40. glReadPixels(point.x, point.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixelColors[0]);
  41. #else
  42. glReadPixels(point.x, point.y, 1, 1, GL_ALPHA, GL_UNSIGNED_BYTE, &pixelColors[0]);
  43. #endif
  44.  
  45. int alpha = pixelColors[0];
  46. CCLOG("----alpha %d", alpha);
  47.  
  48. renderer->end();
  49.  
  50. selectSprite->setPosition(cutPos);
  51.  
  52. if (alpha <= 20)
  53. {
  54. isTouchClaimed = false;
  55. }
  56. else
  57. {
  58. isTouchClaimed = true;
  59. }
  60. // check claimed touch arena
  61. }
  62. else
  63. {
  64. isTouchClaimed = true;
  65. }
  66. return isTouchClaimed;
  67. }

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

AlphaTouchCheck

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

在lua里面能够提供检測开关 是否对透明纸进行检測咯。

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

Cocos2dx Widget button透明区域过滤的更多相关文章

  1. 解决Android中No resource found that matches android:TextAppearance.Material.Widget.Button.Inverse问题

    解决Android中No resource found that matches android:TextAppearance.Material.Widget.Button.Inverse问题http ...

  2. 加载程序到android虚拟机报错: android.widget.RelativeLayout cannot be cast to android.widget.Button

    05-23 02:53:48.416: E/Trace(875): error opening trace file: No such file or directory (2) 05-23 02:5 ...

  3. android:TextAppearance.Material.Widget.Button.Inverse找不到或者报错问题

    前两天将android sdk升到android6.0后出现Error retrieving parent for Item - AppCompact-v7 23 或者无法解析 android:Tex ...

  4. android:TextAppearance.Material.Widget.Button.Inverse问题

    如果在刚够构建Android Studio项目的时候,运行发现,出现没找到资源的错误!找不到com.android.support/appcompat-v7/23.0.1/res/values-v23 ...

  5. TextAppearance.Material.Widget.Button.Inverse,Widget.Material.Button.Colored

    编译xamarin android项目报错: android:TextAppearance.Material.Widget.Button.Inverse android:Widget.Material ...

  6. lua 中处理cocos2dx 的button 事件

    lua 中处理cocos2dx 的button 事件 2014-05-08 09:44:32|  分类: lua |举报 |字号 订阅   1.引入这个类:require "GuiConst ...

  7. java.lang.ClassCastException:android.widget.Button cannot be cast to android.widget.ImageView

    今天遇到一个错误也不知道怎么回事,上网搜了一下: 出现的问题是:java.lang.ClassCastException:android.widget.Button cannot be cast to ...

  8. cocos2dx CCControlButton button大事

    =================================.cpp文件 <pre name="code" class="cpp">bool ...

  9. cocos2dx --- Widget 载入中 CCNode

    如果说. Widget 有addChild()   与 addNode()  两个方法. 如今我要载入一个粒子特效进去,下图: Widget* layout = dynamic_cast<Wid ...

随机推荐

  1. ActiveMQ之二--JMS消息类型

    1.前言 //发送文本消息 session.createTextMessage(msg); //接受文本消息 public void onMessage(Message msg) { TextMess ...

  2. CDB和PDB基本管理

    CDB和PDB基本管理 这篇文章主要介绍CDB和PDB的基本管理,资料来源oracle官方. 基本概念: Multitenant Environment:多租户环境 CDB(Container Dat ...

  3. Provider 错误 '80004005' 未指定的错误 的最终解决方法

    今天在配置公司的香港WEB服务器Server2003系统,建好应用程序池后,发现远行程序经常出现下面的错误,刷新几下又可以,但过不了多久又是出现下面的错误!! 在网上查找相关问题得知,这是2003SP ...

  4. C# 异步操作 async await 的用法

    1. async与 await 成对出现 async 在方法前使用 ,方法体面面用  await . 2. 使用async 和await定义异步方法不会创建新线程. 3.await 后面一定是一个扫行 ...

  5. 高质量代码之HTML、CSS篇

    HTML篇 使用语义化标签<strong><fieldset><legend><ul>等等,少用<div><span> 判断网页 ...

  6. IE对toLocaleString小数位处理

    在js中对数值的格式化经常会用到四舍五入.保留小数位数.百分制格式化,分别会用到以下方法 <script type="text/javascript"> var n = ...

  7. 如何引用CSS样式表

      如何使用样式 当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化.有以下三种方式来插入样式表: 1.外部样式表 当样式需要被应用到很多页面的时候,外部样式表将是理想的选择.使用外部样式 ...

  8. Scrum概述

    • 敏捷方法是一类软件开发流程的泛称: • 敏捷方法是相对于传统的瀑布式软件过程提出的: • 敏捷方法可以用敏捷宣言(4条).敏捷原则(12条)来概括: • 敏捷原则通过一系列的敏捷实践来体现出来: ...

  9. 在Mac OS X 10.9上安装 Thrift 0.9.1

    Thrift 0.9.1 官方文档中对于Mac OS X上的安装描述适合 10.8,但不适用于10.9. Homebrew  macport 默认都不能在 10.9上安装Thrift 0.9.1成功 ...

  10. 编译python3

    安装环境 yum install gcc yum install zlib-devel yum install make 下载python版本 wget http://www.python.org/f ...