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

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

enter image description here

Как я могу это сделать? Благодарю.

 SpaceDog05 июн. 2012 г., 04:50
шаблон представляет прозрачность. Да, я знаю, как обнаруживать касания, я просто проверяю, находится ли касание внутри sprite.boundingBox ... мне нужно знать, находится ли оно внутри boundingBox и является непрозрачным пикселем.
 SpaceDog05 июн. 2012 г., 20:43
да, я хочу, чтобы он игнорировал любое прикосновение к прозрачной области слоя, но если есть слой ниже, и эта точка касания соответствует непрозрачной точке на этом слое, я хочу, чтобы этот слой был запущен ниже.
 giorashc05 июн. 2012 г., 12:29
Хотите, чтобы касание проходило через прозрачные области? (то есть самый верхний слой является прозрачным, но вы касаетесь его в положении, где на нижнем слое находится непрозрачный пиксель в том же месте)
 SimplyKiwi05 июн. 2012 г., 02:35
Прозрачный слой прозрачный или это рисунок, как показано выше? Также вы уже знаете, как обнаружить прикосновения на ЛЮБОЙ области?
 SimplyKiwi05 июн. 2012 г., 05:03
Хм, хорошо, так что я рекомендую просто поместить пустой CCMenuItemImage на непрозрачный родительский элемент и сделать это таким образом. В противном случае вы будете иметь дело с большим количеством пиксельного кода, который вам не нужен.

Ответы на вопрос(4)

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

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

дайте мне знать, работает ли оно или нет

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

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

Решение Вопроса

Реализуйте расширение на 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);
}
 17 авг. 2012 г., 00:32
Можете ли вы расширить ответ? Я попытался сделать "расширение", но должно ли это быть на самом деле категорией? Также kHITTEST_WIDTH и kHITTEST_HEIGHT не определены. Должны ли они быть 1x1 или 40x40? Может кто-нибудь опубликовать все решение?
 SpaceDog05 июн. 2012 г., 20:44
вот и все! Спасибо!!!!!
 17 авг. 2012 г., 14:13
Здравствуйте, расширение действительно категория для этого класса. Вы можете создать его и сразу добавить этот метод как его часть. Что касается неопределенных констант, вы можете заменить их на 1.

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

Ваш ответ на вопрос