Cocos2d 2.0 - Игнорирование штрихов к прозрачным областям слоев/спрайтов

У меня есть приложение, в котором у меня есть несколько слоев, созданных из изображений PNG с прозрачностью. Эти слои находятся на экране друг над другом. Мне нужно уметь игнорировать штрихи, передаваемые прозрачным областям слоев, и просто быть в состоянии обнаружить как касания, когда пользователь нажимает на непрозрачную область слоя... см. Рис....

enter image description here

Как мне это сделать? спасибо.

Ответы

Ответ 1

Здесь у вас есть возможное решение.

Внедрить расширение на 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 alpha byte is transparent
    return (pixel[3] == 0);
}

Ответ 2

Если решение Lio не работает, вы можете добавить добавить прозрачный спрайт в качестве вашего ребенка, разместить его прямо под своей непрозрачной областью с размером этой непрозрачной области и выдержать все касания этим новым прозрачным спрайтом, но не по оригинальному спрайту.

Ответ 3

Вот мое решение вашего требования, сообщите мне, работает ли оно или нет.

Создать категорию в CCMenu с именем Transparent Файл 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. Его работа прекрасна здесь.. дайте мне знать, если вы столкнетесь с любыми проблемами

-Пареш Ратод Cocos2d Lover

Ответ 4

Решение, которое отлично подойдет для меня, это использовать листы Sprite. Я использую TexturePacker для создания листов спрайтов. Шаги по созданию спрайт-листа с помощью TexturePacker: 1. Загрузите все изображения (.png) в TexturePacker. 2. Выберите формат данных как coco2d и выберите PVR в качестве формата текстуры. 3. Загрузите лист спрайтов в свой код и извлеките изображения из листа спрайтов.

Подробное описание можно найти здесь.