16

我有一个应用程序,其中有几个由具有透明度的 PNG 图像创建的图层。这些图层都在屏幕上彼此重叠。当用户点击图层的非透明区域时,我需要能够忽略对图层透明区域的触摸,并且能够检测为触摸......参见图片......

在此处输入图像描述

我怎么做?谢谢。

4

4 回答 4

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);
}
于 2012-06-05T08:09:01.657 回答
0

如果 Lio 的解决方案不起作用,您可以添加透明精灵作为您的孩子,将其放置在您的非透明区域下方,大小与此非透明区域相同,并通过这个新的透明精灵恢复所有触摸,但不能通过原始精灵。

于 2012-06-05T09:33:41.193 回答
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 情人

于 2014-03-06T16:58:27.223 回答
-1

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

详细描述可以在这里找到。

于 2014-09-10T10:33:18.610 回答