cocos2d-x像素级触摸处理

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

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

#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"

using namespace cocos2d;
using namespace CocosDenshion;

CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();

    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

bool HelloWorld::init()
{
    if (!CCLayer::init()){
        return false;
    }

    this->setTouchEnabled(true);

    this->m_imgMan = CCSprite::create("man.png");
    this->m_imgMan->setPosition(ccp(400, 200));
    this->addChild(this->m_imgMan, 1);

    this->m_pRenderTexture = CCRenderTexture::create(this->m_imgMan->getContentSize().width, this->m_imgMan->getContentSize().height, kCCTexture2DPixelFormat_RGBA8888);
    this->m_pRenderTexture->ignoreAnchorPointForPosition(true);
    this->m_pRenderTexture->setPosition(ccp(400, 200));
    this->m_pRenderTexture->setAnchorPoint(CCPointZero);
    this->addChild(this->m_pRenderTexture, 0, 1);

    return true;
}

bool HelloWorld::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) {

    bool isTouched = false;

    CCPoint touchPoint = pTouch->getLocationInView();
    CCPoint glPoint = CCDirector::sharedDirector()->convertToGL(touchPoint);

    if (this->m_imgMan->boundingBox().containsPoint(glPoint)) {

        ccColor4B color4B = {0, 0, 0, 0};

        CCPoint nodePos = this->m_imgMan->convertTouchToNodeSpace(pTouch);
        unsigned int x = nodePos.x;
        unsigned int y = this->m_imgMan->getContentSize().height - nodePos.y;

        CCPoint point = this->m_imgMan->getPosition();
        //开始准备绘制
        this->m_pRenderTexture->begin();
        //绘制使用的临时精灵,与原图是同一图片
        CCSprite* pTempSpr = CCSprite::createWithSpriteFrame(this->m_imgMan->displayFrame());
        pTempSpr->setPosition(ccp(pTempSpr->getContentSize().width / 2, pTempSpr->getContentSize().height / 2));
        //绘制
        pTempSpr->visit();
        //结束绘制
        this->m_pRenderTexture->end();
        //通过画布拿到这张画布上每个像素点的信息,封装到CCImage中
        CCImage* pImage = this->m_pRenderTexture->newCCImage();
        //获取像素数据
        unsigned char* data_ = pImage->getData();
        unsigned int *pixel = (unsigned int *)data_;
        pixel = pixel + (y * (int)pTempSpr->getContentSize().width) * 1 + x * 1;
        //R通道
        color4B.r = *pixel & 0xff;
        //G通道
        color4B.g = (*pixel >> 8) & 0xff;
        //B通过
        color4B.b = (*pixel >> 16) & 0xff;
        //Alpha通道,我们有用的就是Alpha
        color4B.a = (*pixel >> 24) & 0xff;

        CCLOG("当前点击的点的: alpha = %d", color4B.a);

        if (color4B.a > 50) {
            isTouched = true;
        } else {
            isTouched = false;
        }

        //绘制完成后清理画布的内容
        this->m_pRenderTexture->clear(0, 0, 0, 0);
    }

    if (this->m_pLabTips) {
        this->m_pLabTips->removeFromParentAndCleanup(true);
        this->m_pLabTips = NULL;
    }

    return isTouched;
}

void HelloWorld::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) {

    if (this->m_pLabTips) {
        this->m_pLabTips->removeFromParentAndCleanup(true);
        this->m_pLabTips = NULL;
    }

    this->m_pLabTips = CCLabelTTF::create("点击到非透明的像素点", "Courier", 30);
    this->m_pLabTips->setAnchorPoint(CCPointZero);
    this->m_pLabTips->setPosition(ccp(300.0f, 100.0f));
    this->m_pLabTips->setColor(ccYELLOW);
    this->addChild(this->m_pLabTips, 1);

}

void HelloWorld::registerWithTouchDispatcher() {
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, CCLayer::getTouchPriority(), false);
}

当点击到了有色点时,我让屏幕上显示黄字提示,并观察打印日志信息:

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

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

本文由CC原创总结,如需转载请注明出处:http://blog.csdn.net/oktears/article/details/37993871

时间: 2024-08-10 15:02:12

cocos2d-x像素级触摸处理的相关文章

显示对象的像素级碰撞检测

mc2.gotoAndStop(1); var bmd1 = new BitmapData(mc1.width, mc1.height, true, 0); bmd1.draw(mc1); var bmd2 = new BitmapData(mc2.width, mc2.height, true, 0); bmd2.draw(mc2); stage.addEventListener(Event.ENTER_FRAME,frameFunc); function frameFunc(e:Event)

OpenCV中feature2D学习——亚像素级角点检测(cornerSubPix)

概述 除了利用Harris进行角点检测和利用Shi-Tomasi方法进行角点检测外,还可以使用cornerEigenValsAndVecs()函数和cornerMinEigenVal()函数自定义角点检测函数.如果对角点的精度有更高的要求,可以用cornerSubPix()函数将角点定位到子像素,从而取得亚像素级别的角点检测效果. cornerSubPix()函数 (1)函数原型 cornerSubPix()函数在角点检测中精确化角点位置,其函数原型如下: C++: void cornerSub

亚像素级角点定位

代码示例: #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> #include <stdlib.h> using namespace cv; using namespace std; #define WINDOW_NAME "Shi-Tom

OpenCv_cvFindCornerSubPix()查找亚像素级角点

如果我们进行图像处理的目的不是用于识别特征点而是进行稽核测量,则通常需要更高的精度,而cvGoodFeatureToTrack()只能提供简单的像素坐标值,但有时候我们会需要实际坐标值而不是证书坐标值,例如,我们想要确定图形中一个尖锐的峰值点的位置,但是峰值点的位置一般都不会位于一个像素点的正中心,,这时候就可以使用亚像素检测方法. 亚像素级角点的位置在社星际标定.跟踪并重建蛇形阿基的轨迹或者重建被跟踪目标的三维结构时就是一个基本的测量值.通过cvGoodFeaturesToTrack()函数可

OpenCV亚像素级的角点检测

亚像素级的角点检测 目标 在本教程中我们将涉及以下内容: 使用OpenCV函数 cornerSubPix 寻找更精确的角点位置 (不是整数类型的位置,而是更精确的浮点类型位置). 理论 代码 这个教程的代码如下所示.源代码还可以从 这个链接下载得到 #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #inclu

分享一位国外大牛写的不规则物体像素级碰撞检测算法及详解

最近在做一个有关投篮的小游戏,需要用到像素级碰撞检测,as3自带的hitTestObject显然无法满足需要.网上搜寻了一下,在9ria挖坟挖到两篇好文章: 分享一个超高效的不规则物体碰撞检测的类~~ [Lii]超高效的不规则物体碰撞检测<效率优化> 第一篇文章介绍了一位国外大牛写的不规则物体像素级碰撞检测算法,原理是用bitmap绘制两对象不透明区域,利用混合模式计算出两对象的相交区域. 第二篇文章则在该算法的基础上进行了效率的优化,原理是判断出两对象发生hitTestObject碰撞后,将

三维精密测量(一) —— 一种求圆标志中心亚像素级边缘标定算法

一.边缘细定位边缘 1 参数拟合法的基本原理 CCD是光积分器件,它以固定大小的面积在固定的时间间隔内对投影其感光面上的光强进行积分,输出的结果就是图像的灰度值.由于CCD的积分时间和面积是相对固定的,所以它的输出灰度值只与感光面上光强分布有关.对于某一像素的灰度值输出可以表示为 原文地址:https://www.cnblogs.com/fujj/p/9678658.html

【练习8.7】cvGoodFeaturesToTrack确定图像强角点、cvFindCornerSubPix亚像素级角点检测

页内索引 题目要求 程序代码 结果图片 要言妙道 借鉴参考 题目要求: 黑色背景上创建一个白色拐角,使得这个角正好在整数值的坐标上,保存用OpenCV打开 a.找出并输出拐角的确切坐标 分别改变原始图像进行如下操作 b.用白边透明填充的圆将圆角遮住 c.用白边黑色填充的圆将圆角遮住 d.用黑色圆块将圆角遮住 程序代码: 1 // OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点. 2 // 3 // string file_full_name = "D:\\Wo

[ActionScript 3.0] 像素级碰撞检测

1 package 2 { 3 import flash.display.BitmapData; 4 import flash.display.BlendMode; 5 import flash.display.DisplayObject; 6 import flash.display.Sprite; 7 import flash.geom.ColorTransform; 8 import flash.geom.Matrix; 9 import flash.geom.Point; 10 impo