2012-06-04 12 views
15

Mam aplikację, w której mam kilka warstw utworzonych z obrazów PNG z przezroczystością. Te warstwy znajdują się na ekranie ponad sobą. Muszę być w stanie ignorować dotknięcia nadane przezroczystym obszarom warstw i po prostu być w stanie wykryć dotyk, gdy użytkownik dotknie nieprzezroczystego obszaru warstwy ... zobacz zdjęcie ...Cocos2d 2.0 - Ignorowanie dotyku przezroczystych obszarów warstw/sprite'ów

Jak to zrobić? dzięki.

+0

Czy przezroczysta warstwa jest przezroczysta, czy jest to wzór, jak pokazano powyżej? Czy wiesz już, jak wykryć dotknięcia na DOWOLNYM obszarze? –

+0

Wzór reprezentuje przezroczystość. Tak, wiem, jak wykryć dotyk, po prostu sprawdzam, czy dotyk jest wewnątrz sprite.boundingBox ... potrzebuję wiedzieć, czy jest wewnątrz boundingBox i jest nieprzezroczystym pikselem. – SpaceDog

+0

Hmm, ok, więc polecam tylko umieścić puste CCMenuItemImage na nieprzejrzystym rodzicu i zrobić to w ten sposób. W przeciwnym razie będziesz miał do czynienia z DUŻĄ ilością pikseli, których nie chcesz. –

Odpowiedz

6

Tutaj masz możliwe rozwiązanie.

Wdrożenie rozszerzenie na CCLayer i dostarczenie tej metody:

- (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); 
} 
+0

to wszystko! Dzięki!!!!! – SpaceDog

+0

Czy możesz rozwinąć odpowiedź. Próbowałem zrobić "rozszerzenie", ale czy rzeczywiście powinno to być kategorią? Również kHITTEST_WIDTH i kHITTEST_HEIGHT są niezdefiniowane. Czy powinny to być 1x1 czy 40x40?Czy ktoś może opublikować całe rozwiązanie? – mevdev

+0

Witaj, rozszerzenie jest rzeczywiście kategorią tej klasy. Możesz go utworzyć i od razu dodać tę metodę jako część. Jeśli chodzi o niezdefiniowane stałe, możesz zastąpić je 1. – Lio

0

jeśli rozwiązanie Lio nie działa, można dodać dodać przezroczystą sprite jako dziecko Pozdrawiam, umieścić go tuż pod nieprzezroczystej powierzchni z rozmiarem tego niepoddającego się procesowi obszaru i odżywają wszystkie dotknięcia tego nowego przezroczystego duszka, ale nie oryginalnego duszka.

0

Oto moje rozwiązanie do Państwa wymagań, daj mi znać, czy to działa, czy nie

utworzyć kategorię na CCMenu z nazwą Przejrzysta pliku CCMenu + Tranparent.h

#import "CCMenu.h" 

@interface CCMenu (Transparent) 
@end 

pliku 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 

Spowoduje to sprawdzenie piksela w celu zwrócenia elementu CCMenuItem. jego pracy dobrze tutaj .. daj mi znać, jeśli napotkają żadnych problemów

-Paresh Rathod Cocos2d Lover

-1

Rozwiązanie, które pracowały dla mnie świetnie się przy użyciu arkuszy ikonki. Używam TexturePackera do tworzenia arkuszy sprite. Kroki tworzenia arkusza sprite za pomocą TexturePacker: 1. Załaduj wszystkie pliki obrazów (.png) do TexturePackera. 2. Wybierz format danych jako coco2d i wybierz PVR jako format tekstury. 3. Załaduj arkusz sprite do kodu i wyodrębnij obrazy z arkusza sprite.

Szczegółowy opis można znaleźć here.