文档章节

cocos2d-x像素级触摸处理

piggybear
 piggybear
发布于 2015/02/16 10:28
字数 856
阅读 23
收藏 1

最近研究了一下像素级的触摸处理,有时候我们用一个不规则的图形作为一个按钮,这个不规则的图形是一张矩形的png图片,很可能图片的实际有效的显示内容只占整个png图片的很小一部分,剩下的大部分都是png图片的透明区域,我们想把这部分透明区域过滤掉,实现一个触摸到真实的内容才会有按钮响应的效果。

刚开始试图通过CCSprite直接获取到纹理的像素信息,但是cocos2d-x并没有给我们提供直接通过CCSprite获取像素信息的接口,研究了几个网上的Demo,发现通过使用RenderTexture重绘可以实现这一效果,下面把代码贴出来。

[cpp]  view plain copy
  1. #include "HelloWorldScene.h"  
  2. #include "SimpleAudioEngine.h"  
  3.   
  4. using namespace cocos2d;  
  5. using namespace CocosDenshion;  
  6.   
  7. CCScene* HelloWorld::scene()  
  8. {  
  9.     // 'scene' is an autorelease object  
  10.     CCScene *scene = CCScene::create();  
  11.       
  12.     // 'layer' is an autorelease object  
  13.     HelloWorld *layer = HelloWorld::create();  
  14.   
  15.     // add layer as a child to scene  
  16.     scene->addChild(layer);  
  17.   
  18.     // return the scene  
  19.     return scene;  
  20. }  
  21.   
  22. bool HelloWorld::init()  
  23. {  
  24.     if (!CCLayer::init()){  
  25.         return false;  
  26.     }  
  27.       
  28.     this->setTouchEnabled(true);  
  29.   
  30.     this->m_imgMan = CCSprite::create("man.png");  
  31.     this->m_imgMan->setPosition(ccp(400, 200));  
  32.     this->addChild(this->m_imgMan, 1);  
  33.       
  34.     this->m_pRenderTexture = CCRenderTexture::create(this->m_imgMan->getContentSize().width, this->m_imgMan->getContentSize().height, kCCTexture2DPixelFormat_RGBA8888);  
  35.     this->m_pRenderTexture->ignoreAnchorPointForPosition(true);  
  36.     this->m_pRenderTexture->setPosition(ccp(400, 200));  
  37.     this->m_pRenderTexture->setAnchorPoint(CCPointZero);  
  38.     this->addChild(this->m_pRenderTexture, 0, 1);  
  39.   
  40.       
  41.     return true;  
  42. }  
  43.   
  44. bool HelloWorld::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) {  
  45.       
  46.     bool isTouched = false;  
  47.       
  48.     CCPoint touchPoint = pTouch->getLocationInView();  
  49.     CCPoint glPoint = CCDirector::sharedDirector()->convertToGL(touchPoint);  
  50.   
  51.   
  52.     if (this->m_imgMan->boundingBox().containsPoint(glPoint)) {  
  53.       
  54.         ccColor4B color4B = {0, 0, 0, 0};  
  55.           
  56.         CCPoint nodePos = this->m_imgMan->convertTouchToNodeSpace(pTouch);  
  57.         unsigned int x = nodePos.x;  
  58.         unsigned int y = this->m_imgMan->getContentSize().height - nodePos.y;  
  59.           
  60.         CCPoint point = this->m_imgMan->getPosition();  
  61.         //开始准备绘制  
  62.         this->m_pRenderTexture->begin();  
  63.         //绘制使用的临时精灵,与原图是同一图片  
  64.         CCSprite* pTempSpr = CCSprite::createWithSpriteFrame(this->m_imgMan->displayFrame());  
  65.         pTempSpr->setPosition(ccp(pTempSpr->getContentSize().width / 2, pTempSpr->getContentSize().height / 2));  
  66.         //绘制  
  67.         pTempSpr->visit();  
  68.         //结束绘制  
  69.         this->m_pRenderTexture->end();  
  70.         //通过画布拿到这张画布上每个像素点的信息,封装到CCImage中  
  71.         CCImage* pImage = this->m_pRenderTexture->newCCImage();  
  72.         //获取像素数据  
  73.         unsigned char* data_ = pImage->getData();  
  74.         unsigned int *pixel = (unsigned int *)data_;  
  75.         pixel = pixel + (y * (int)pTempSpr->getContentSize().width) * 1 + x * 1;  
  76.         //R通道  
  77.         color4B.r = *pixel & 0xff;  
  78.         //G通道  
  79.         color4B.g = (*pixel >> 8) & 0xff;  
  80.         //B通过  
  81.         color4B.b = (*pixel >> 16) & 0xff;  
  82.         //Alpha通道,我们有用的就是Alpha  
  83.         color4B.a = (*pixel >> 24) & 0xff;  
  84.           
  85.         CCLOG("当前点击的点的: alpha = %d", color4B.a);  
  86.           
  87.         if (color4B.a > 50) {  
  88.             isTouched = true;  
  89.         } else {  
  90.             isTouched = false;  
  91.         }  
  92.           
  93.         //绘制完成后清理画布的内容  
  94.         this->m_pRenderTexture->clear(0, 0, 0, 0);  
  95.     }  
  96.       
  97.       
  98.     if (this->m_pLabTips) {  
  99.         this->m_pLabTips->removeFromParentAndCleanup(true);  
  100.         this->m_pLabTips = NULL;  
  101.     }  
  102.       
  103.     return isTouched;  
  104. }  
  105.   
  106.   
  107. void HelloWorld::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) {  
  108.       
  109.     if (this->m_pLabTips) {  
  110.         this->m_pLabTips->removeFromParentAndCleanup(true);  
  111.         this->m_pLabTips = NULL;  
  112.     }  
  113.       
  114.     this->m_pLabTips = CCLabelTTF::create("点击到非透明的像素点""Courier", 30);  
  115.     this->m_pLabTips->setAnchorPoint(CCPointZero);  
  116.     this->m_pLabTips->setPosition(ccp(300.0f, 100.0f));  
  117.     this->m_pLabTips->setColor(ccYELLOW);  
  118.     this->addChild(this->m_pLabTips, 1);  
  119.   
  120. }  
  121.   
  122. void HelloWorld::registerWithTouchDispatcher() {  
  123.     CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, CCLayer::getTouchPriority(), false);  
  124. }  
当点击到了有色点时,我让屏幕上显示黄字提示,并观察打印日志信息:



当点击到了透明的黑色区域时,屏幕上不显示任何文字,观察打印日志信息:



实现的原理:我通过点击的时候把图片进行重绘,重绘的过程中,可以通过RenderTexture也就是画布,把整个画布上的像素点信息全部拿到,我让绘制的内容和画布的大小是一样的,所以就能保证画布上的每一个像素点就是我想要绘制的图片的像素点,然后通过判断像素点的alpha通道值,来确定这个点是否是透明色的,如果是透明色则不做触摸响应。



本文转载自:http://blog.csdn.net/aa294194253/article/details/38701893

共有 人打赏支持
piggybear
粉丝 3
博文 237
码字总数 37552
作品 0
西安
技术主管
私信 提问
忍者无敌-实例讲解Cocos2d-x瓦片地图

实例比较简单,如图所示,地图上有一个忍者精灵,玩家点击他周围的上、下、左、右,他能够向这个方向行走。当他遇到障碍物后是无法穿越的,障碍物是除了草地以为部分,包括了:树、山、河流等...

智捷课堂
2014/09/19
0
1
Cocos2d-JS事件处理机制

在很多图形用户技术中,事件处理机制一般都有三个重要的角色:事件、事件源和事件处理者。事件源是事件发生的场所,通常就是各个视图或控件,事件处理者是接收事件并对其进行处理的一段程序。...

智捷课堂
2015/03/31
0
0
实例介绍Cocos2d-x中Box2D物理引擎:HelloBox2D

我们通过一个实例介绍一下,在Cocos2d-x 3.x中使用Box2D物理引擎的开发过程,熟悉这些API的使用。这个实例运行后的场景如图所示,当场景启动后,玩家可以触摸点击屏幕,每次触摸时候,就会在...

智捷课堂
2014/10/08
0
0
十 手游开发神器 cocos2d-x editor 之触摸事件

这一节 我将实现让小怪物跟随我的触摸方向移动,同时触摸的地方产生一个四周发散的效果 效果如下: 代码下载:http://www.kuaipan.cn/file/id25348935635744782.htm?source=1 打开MainLayer...

makeapp628
2014/01/25
0
0
COCOS2DX 3.X 解决TABLEVIEW 、SCROLLVIEW上的MENU问题

本站文章均为 罗汉果 cocos2d-x技术博客 原创,转载务必在明显处注明: 转载自 【罗汉果 cocos2d-x技术博客】 原文链接: http://tech.pigsns.com/thread-228-1-1.html 问题有两个(我主要解决...

汉果James
2014/08/27
0
2

没有更多内容

加载失败,请刷新页面

加载更多

《大漠烟尘》读书笔记及读后感文章3700字

《大漠烟尘》读书笔记及读后感文章3700字: 在这个浮躁的社会里,你有多久没有好好读完一本书了? 我们总觉得自己和别人不一样,所以当看到别人身上的问题时,很少有“反求诸己”,反思自己。...

原创小博客
38分钟前
1
0
大数据教程(9.5)用MR实现sql中的jion逻辑

上一篇博客讲解了使用jar -jar的方式来运行提交MR程序,以及通过修改YarnRunner的源码来实现MR的windows开发环境提交到集群的方式。本篇博主将分享sql中常见的join操作。 一、需求 订单数据表...

em_aaron
46分钟前
1
0
十万个为什么之什么是resultful规范

起源 越来越多的人开始意识到,网站即软件,而且是一种新型的软件。这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(high latency)、高并发等特点...

尾生
52分钟前
1
0
Terraform配置文件(Terraform configuration)

Terraform配置文件 翻译自Terraform Configuration Terraform用文本文件来描述设备、设置变量。这些文件被称为Terraform配置文件,以.tf结尾。这一部分将讲述Terraform配置文件的加载与格式。...

buddie
今天
2
0
exportfs命令, vsftp搭建ftp服务

exportfs命令 当修改/etc/exports文件后,更改的内容是不会立即生效的。如果重启nfs服务,会导致客户端重启期间的请求是挂起等待的,可以把客户端的挂载umount进行卸载后,再重启nfs服务,但...

野雪球
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部