小伟哥 遇到一个命题:

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

让点击也没有效果滴啦。

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

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

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

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

上面是按键检測的逻辑。

以下是改动过的代码。原理非常easy  在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里面能够提供检測开关 是否对透明纸进行检測咯。

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

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. HTTP协议学习笔记-1

    基本概念 首先需要了解几个概念: WEB客户端和服务器: WEB客户端当然就是指我们用使用的某个网站 服务器就是WEB资源源头,我们从服务器去请求数据,服务器把请求的数据发给WEB客户端 媒体类型: ...

  2. Python 用 os.walk 遍历目录

    今天第一次进行 文件遍历,自己递归写的时候还调试了好久,(主要因为分隔符号的问题),后来发现了os.walk方法,就忍不住和大家分享下. 先看下代码: import os for i in os.wa ...

  3. scrollTop

    scrollTop 表示滚动的高度,默认从position:0;开始向下滚,scrollTop(offset)的offset表示相对顶部的偏移,以像素计,<br/> scrollTop() ...

  4. (转)PHP开发框架浅析

    开发框架的定义我没有找到很准确的描述,下面几句话基本概括了开发框架的的功能和用途 框架是一种应用程序的半成品: 框架就像是人的骨骼一样: 框架是一组可复用的组件: 框架是一个可复用的设计构件…… 简而 ...

  5. Strider SSH Deploy配置

    登录需要ssh, ssh 免密码登录配置自行百度.shell里写成自己的需要的命令

  6. freetds相关

    什么是FreeTDS  简单的说FreeTDS是一个程序库,可以实现在Linux系统下访问微软的SQL数据库! FreeTDS 是一个开源(如果你喜欢可以称为自由)的程序库,是TDS(表列数据流 )协 ...

  7. 【全国互虐】Fibonacci矩阵

    orz啊又被屠了 人生如此艰难 题意: 给定一个k维的n^k的超立方体 超立方体的元素Ai1,i2,...,ik 的值为f(i1+i2+...+ik-k+1) f为斐波那契数列 求该超立方体的所有元素 ...

  8. js运动 模仿淘宝幻灯

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  9. ubuntu下设置开机自动挂载硬盘

    我们在linux中常常用mount命令把硬盘分区或者光盘挂载到文件系统中./etc/fstab就是在开机引导的时候自动挂载到linux的文件系统. 如果给计算机配了一块新磁盘,已经分区,格式化,挂载, ...

  10. UVALive 3953 Strange Billboard (状态压缩+枚举)

    Strange Billboard 题目链接: http://acm.hust.edu.cn/vjudge/contest/129733#problem/A Description The marke ...