Cocos2d 2.0 - 忽略对图层/精灵的透明区域的触摸

时间:2012-06-04 22:16:45

标签: cocos2d-iphone

我有一个应用程序,我从PNG图像创建了几个透明度的图层。这些图层都在屏幕上相互叠加。我需要能够忽略给予透明图层区域的触摸,并且当用户点击图层的非透明区域时能够检测到触摸...请参阅图片...

enter image description here

我该怎么做?感谢。

4 个答案:

答案 0 :(得分:6)

这里有一个可能的解决方案。

在CCLayer上实现扩展并提供此方法:

- (BOOL)isPixelTransparentAtLocation:(CGPoint)loc 
{   
    //Convert the location to the node space
    CGPoint location = [self convertToNodeSpace:loc];

    //This is the pixel we will read and test
    UInt8 pixel[4];

    //Prepare a render texture to draw the receiver on, so you are able to read the required pixel and test it    
    CGSize screenSize = [[CCDirector sharedDirector] winSize];
    CCRenderTexture* renderTexture = [[CCRenderTexture alloc] initWithWidth:screenSize.width
                                                                     height:screenSize.height
                                                                pixelFormat:kCCTexture2DPixelFormat_RGBA8888];

    [renderTexture begin];

    //Draw the layer
    [self draw];    

    //Read the pixel
    glReadPixels((GLint)location.x,(GLint)location.y, kHITTEST_WIDTH, kHITTEST_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, pixel);

    //Cleanup
    [renderTexture end];
    [renderTexture release];

    //Test if the pixel's alpha byte is transparent
    return (pixel[3] == 0);
}

答案 1 :(得分:0)

如果Lio的解决方案不起作用,你可以添加透明精灵作为你的孩子,将它放在你的非透明区域下面,这个非透明区域的大小,并通过这个新的透明精灵重新进行所有触摸,但不是原始的精灵。

答案 2 :(得分:0)

以下是我对您的要求的解决方案,让我知道它是否有效

在CCMenu上创建一个名称透明的类别 文件CCMenu + Tranparent.h

#import "CCMenu.h"

@interface CCMenu (Transparent)
@end

档案CCMenu + Tranparent.m

#import "CCMenu+Transparent.h"
#import "cocos2d.h"
@implementation CCMenu (Transparent)
-(CCMenuItem *) itemForTouch: (UITouch *) touch{
    CGPoint touchLocation = [touch locationInView: [touch view]];
    touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];

    CCMenuItem* item;
    CCARRAY_FOREACH(children_, item){
        UInt8 data[4];

        // ignore invisible and disabled items: issue #779, #866
        if ( [item visible] && [item isEnabled] ) {
            CGPoint local = [item convertToNodeSpace:touchLocation];
            /*
             TRANSPARENCY LOGIC
             */
            //PIXEL READING 1 PIXEL AT LOCATION


            CGRect r = [item rect];
            r.origin = CGPointZero;

            if( CGRectContainsPoint( r, local ) ){
                if([NSStringFromClass(item.class) isEqualToString:NSStringFromClass([CCMenuItemImage class])]){
                    CCRenderTexture* renderTexture = [[CCRenderTexture alloc] initWithWidth:item.boundingBox.size.width * CC_CONTENT_SCALE_FACTOR()
                                                                                     height:item.boundingBox.size.height * CC_CONTENT_SCALE_FACTOR()
                                                                                pixelFormat:kCCTexture2DPixelFormat_RGBA8888];

                    [renderTexture begin];
                    [[(CCMenuItemImage *)item normalImage] draw];

                    data[3] = 1;
                    glReadPixels((GLint)local.x,(GLint)local.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);

                    [renderTexture end];
                    [renderTexture release];
                    if(data[3] == 0){
                        continue;
                    }

                }
                free(data);
                return item;
            }

        }
    }
    return nil;
}

@end

这将检查返回CCMenuItem的像素。 它在这里工作正常..如果您遇到任何问题,请告诉我

-Paresh Rathod Cocos2d Lover

答案 3 :(得分:-1)

对我来说很有效的解决方案是使用Sprite表。我使用TexturePacker来创建精灵表。使用TexturePacker创建精灵表的步骤: 1.将所有图像(.png)文件加载到TexturePacker中。 2.选择数据格式为coco2d并选择PVR作为纹理格式。 3.将精灵表加载到代码中,并从精灵表中提取图像。

详细说明可以here