2010-07-05 13 views
14

¿Cómo puedo recortar/recortar/enmascarar o simplemente configurar el marco de un CCSprite en Cocos2D?iPhone Cocos2d - Sprite cliping/mask/frame

algo similar a: establecer el marco para UIView, con subvistas recorte = VERDADERO

Mi CCSprite principal Sprite tiene múltiples Niño Sprite añadido a la misma. Solo quiero Máscara parte de esa Principal Sprite Sprite visible. ¿Hay alguna manera de recortar o usar una máscara para CCSprite?

Podría cortar el fondo y la capa encima, dejando solo esa área visible, ¿pero es la única?

aquí es una imagen de ejemplo que demuestra lo que estoy tratando de lograr: alt text http://dnamique.com/maskSprite.jpg

Respuesta

16

Terminé usando GL_SCISSOR.

en MainSprite I impemented:

- (void) visit 
{ 
    if (!self.visible) { 
     return; 
    } 
    glEnable(GL_SCISSOR_TEST); 
    glScissor(x, y, width, height); 
    [super visit]; 
    glDisable(GL_SCISSOR_TEST); 
} 

Esto recortar o enmascarar el área especificada.

Lo único delicado es que en el modo Paisaje Cocos2D tiene 0,0 en el lado inferior izquierdo de la pantalla, mientras que OpenGL lo tiene en la esquina inferior derecha ya que no tiene en cuenta la orientación de la pantalla.

En otras palabras, para OpenGL considere que tiene una pantalla de retrato rotada.

+0

Otra advertencia: la región de recorte no es relativa al sprite, se basa en el mundo. Por lo tanto, permanecerá en su lugar sin importar cómo se transforme el sprite. Tendrás que moverlo/escalarlo manualmente junto con el sprite si necesitas mover la máscara. – jtalarico

+0

Sí, tienes razón. No me di cuenta de eso al principio. Ahora hice las xey en relación con la posición de mi vista para que siempre se muevan juntas. – Bach

+0

@jtalarico, ¿sabe dónde obtener la transformación de sprite durante la transición utilizando: 'CCDirector :: sharedDirector() -> pushScene (CCTransitionSlideInL :: create (10.0f, pScene))' ¡Gracias! – Zennichimaro

12

Escribí una clase ClippingNode que hace exactamente eso. Puede agregar otros nodos (sprites, etiquetas, etc.) al ClippingNode y solo se dibujarán en la región especificada por ClippingNode. También tiene en cuenta la rotación del dispositivo.

Internamente usa GL_SCISSOR_TEST como en la respuesta de Bach.

http://www.learn-cocos2d.com/2011/01/cocos2d-gem-clippingnode/

+0

+1 porque esta es de hecho una gema – jonsibley

+0

¿Cómo se maneja el nodo de recorte girado? – docchang

3

He intentado utilizar ClippingNode de Steffen Itterheim, pero fue incapaz de ponerse a trabajar en una suficientemente robusto suficiente para mis necesidades de la moda.

Lo creas o no, el siguiente código funciona bastante bien y debe ser código completo. Maneja los cambios de orientación del dispositivo, anchorPoint, posición, escala (scaleX, scaleY). Para cocos2d v2, es posible que sólo tenga que comentario el glPushMatrix y glPopMatrix llamadas ..

Para usarlo, basta con fijar la posición y las propiedades contentSize y agregar el niño/niños que desea engancharse a esta instancia ClippingNode. La propiedad contentSize se usa para definir las dimensiones de la región de recorte.

example of usage: 
ClippingNode *clipNode = [[ClippingNode alloc] init]; 
clipNode.anchorPoint = ccp(0.5f, 0); 
clipNode.position = ccp(100, 25); 
clipNode.contentSize = CGSizeMake(120, 120); 

// add clipNode to your node hierarchy. 
[parentNode addChild:clipNode]; 

// add one or more children to your clipNode: 
[clipNode addChild:child1]; 

// ClippingNode.h 
// CC0 - (public domain. Use in anyway you see fit.) 
// No warranty of any kind is expressed or implied. 
// 
// by UChin Kim. 
// 
// the caller can simply set the regular cocos2d 
// properties: position and contentSize to define the clipping region implicitly (i.e. the 
// position and contentSize of the ClippingNode is the clipping region to be used). 
// as an added bonus, position seems to work as expected (relative to parent node, instead of 
// requiring absolute positioning). 
// 
// also, anchorPoint and scale properties seem to work as expected as well.. 
// no special code is neeed to handle device orientation changes correctly.. 
// 
// To visually see exactly what is being clipped, set the following #define 
// #define SHOW_CLIPPED_REGION_IN_LIGHT_RED 1 
// 

#import "cocos2d.h" 

@interface ClippingNode : CCNode 

@end 

// 
// ClippingNode.m 
// 
#import "ClippingNode.h" 

@implementation ClippingNode 

-(void) visit 
{ 
CGPoint worldOrg = [self convertToWorldSpace:ccp(0, 0)]; 
CGPoint dest = [self convertToWorldSpace:ccp(self.contentSize.width, self.contentSize.height)]; 
CGPoint dims = ccpSub(dest, worldOrg); 

glPushMatrix(); 
glEnable(GL_SCISSOR_TEST); 

glScissor(worldOrg.x, worldOrg.y, dims.x, dims.y); 

#if SHOW_CLIPPED_REGION_IN_LIGHT_RED 
glColor4ub(64, 0, 0, 128); 
ccDrawSolidRect(ccp(0, 0), ccp(1024, 1024)); 
#endif 

[super visit]; 

glDisable(GL_SCISSOR_TEST); 
glPopMatrix(); 
} 

@end 
Cuestiones relacionadas