Qual é a maneira correta de implementar a detecção de ocorrências com sprites não retangulares?

8

Qual é a maneira correta de implementar a detecção de toque ou toque para sprites não retangulares no Cocos2d?

Estou trabalhando em um quebra-cabeça, então nossos sprites têm formas estranhas (tijolos de quebra-cabeça). A partir de agora, implementamos a "detecção" desta maneira:

- (void)selectSpriteForTouch:(CGPoint)touchLocation {  
    CCSprite * newSprite = nil;

    // Loop array of sprites
    for (CCSprite *sprite in movableSprites) {

        // Check if sprite is hit.
        // TODO: Swap if with something better.
        if (CGRectContainsPoint(sprite.boundingBox, touchLocation)) {
            newSprite = sprite;
            break;
        }
    }
    if (newSprite != selSprite) {
        // Move along, nothing to see here
        // Not the problem
    }
}

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
    CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
    [self selectSpriteForTouch:touchLocation];
    return TRUE;
}

Eu sei que o problema está na palavra-chave " sprite.boundingBox". Existe uma maneira melhor de implementar isso ou é uma limitação ao usar sprites baseados em .png? Se sim, como devo proceder?

hogni89
fonte

Respostas:

5

Na verdade, encontrei uma solução simples!

Os objetos dos personagens foram alterados para não apenas incluir informações e sprites, mas também um CGPath. Em seguida, implementou um método, para fazer um loop em todos os objetos de caracteres e verificar se há

CGPathContainsPoint( params ...)

em vez de

CGRectContainsPoint( params ...)

Tutorial que usei: http://www.youtube.com/watch?v=HxHZwzaadNQ - "A mágica do CGPath"

hogni89
fonte
3

Não estou familiarizado com o objetivo C, portanto não posso fornecer nenhum código específico. Mas a maneira geral de realizar coisas como essa é fazer uma verificação de colisão por pixel. Basicamente, funciona exatamente como você o baseia no retângulo, mas antes de disparar o evento de toque, você precisa percorrer todos os pixels tocados e garantir que pelo menos um deles não seja transparente. Isso deve ajudá-lo a se aproximar da resposta, espero que outra pessoa possa fornecer alguns exemplos reais de código sobre o assunto.

Kevin DiTraglia
fonte