2011-04-11 5 views
7

Tengo algunos botones de radio pero la toucharea es demasiado pequeña. La toucharea depende del tamaño de la imagen. ¿Existe una manera elegante de extender el área de contacto con cocos2d sin usar una imagen más grande o crear mis propias áreas táctiles con cgrect? setContentSize haga lo que quiera. Lamentablemente, la imagen se mueve hacia la esquina inferior izquierda de la zona de contenidos. Establecer el punto de anclaje mueve el contenido pero la imagen permanece en la esquina inferior izquierda.cocos2d extienda el área táctil desde un botón

CCMenuItem* pickEasy = [CCMenuItemImage itemFromNormalImage:@"radiobutton_off.png" selectedImage:@"radiobutton_on.png" target:self selector:@selector(pickEasyTapped:)]; 
    pickEasy.position = ccp(ss.width * 0.40, ss.height * 0.78); 
    [pickEasy setContentSize:CGSizeMake(50, 50)]; 

Gracias de antemano.

Respuesta

2

se debe redefinir el método rectInPixels

- (CGRect)rectInPixels 
{ 
CGSize s = [self contentSize]; 
return CGRectMake(0, 0, s.width, s.height); 
} 

- (BOOL)containsTouchLocation:(UITouch *)touch 
{ 
CGPoint p = [self convertTouchToNodeSpace:touch]; 
CGRect r = [self rectInPixels]; 
return CGRectContainsPoint(r, p); 
} 

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event { 

NSSet *allTouches = [event allTouches]; 
for (UITouch *aTouch in allTouches) { 

     if (![self containsTouchLocation:aTouch]) return NO; 
} 

return YES; 
} 

Este dice que el sprite para comprobar que las lejías táctiles dentro de su CGRect alterado

Editar para mostrar subclase CCSprite ---

- (void)onEnter 
{ 
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES]; 
[super onEnter]; 
} 

- (void)onExit 
{ 
[[CCTouchDispatcher sharedDispatcher] removeDelegate:self]; 
[super onExit]; 
} 
+0

Gracias por su respuesta. No sé dónde anular rectInPixels. Después de probar ccnode, ccsprite, ccmenu, ccmenuitem y mi propia clase, encontré una solución alternativa que funciona para mí. – zeiteisen

+0

es una anulación simple de ccsprite, pero debe agregar la clase al CCTouchDispatcher. Ver mi respuesta editada – Bongeh

2

Hice una solución anulando -(CCMenuItem*) itemForTouch:(UITouch *)touch de CCMenu.

 
-(CCMenuItem*) itemForTouch:(UITouch *)touch 
{ 
    CGPoint touchLocation = [touch locationInView:[touch view]]; 
    touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation]; 
    CCMenuItem* item; 
    CCARRAY_FOREACH(children_, item) 
    { 
     if ([item visible] && [item isEnabled]) { 
      CGPoint local = [item convertToNodeSpace:touchLocation]; 
      CGRect r = [item rect]; 
      r.origin = CGPointZero; 
      // increase rect by * 2 
      // a rect at bottom left of the image 
      CGRect bigR = CGRectMake(r.origin.x - r.size.width, r.origin.y - r.size.height, r.size.width * 2, r.size.width * 2); 
      // a rect at top right of the image 
      CGRect bigR2 = CGRectMake(0, 0, r.size.width * 2, r.size.width * 2); 
      if (CGRectContainsPoint(bigR, local) || CGRectContainsPoint(bigR2, local)) { 
       return item; 
      } 
     } 
    } 
    return nil; 
} 

centro de la rect en el medio de la ni de imagen trabajado

11

Tomando el código de respuesta original ...

CCMenuItem* pickEasy = [CCMenuItemImage itemFromNormalImage:@"radiobutton_off.png" selectedImage:@"radiobutton_on.png" target:self selector:@selector(pickEasyTapped:)]; 
pickEasy.position = ccp(ss.width * 0.40, ss.height * 0.78); 
[pickEasy setContentSize:CGSizeMake(50, 50)]; 

... es suficiente con fijar la imagen en la correcta posición ...

[[[pickEasy children] objectAtIndex:0] setAnchorPoint:ccp(0.5,0.5)]; 
[[[pickEasy children] objectAtIndex:1] setAnchorPoint:ccp(0.5,0.5)]; 
[[[pickEasy children] objectAtIndex:0] setPosition:ccp(pickEasy.contentSize.width/2,pickEasy.contentSize.height/2)]; 
[[[pickEasy children] objectAtIndex:1] setPosition:ccp(pickEasy.contentSize.width/2,pickEasy.contentSize.height/2)]; 

... solo con 4 líneas de código! ¡Que te diviertas!

+0

Genius! Esto funcionó perfecto para mí. No pude hacer que las subclases funcionaran correctamente, así que este es un buen truco. Gracias una tonelada. – Arbel

+0

Genius no hace justicia a esto, en mi opinión, la solución perfecta. +1 gracias por compartir. –

4

Además, puede cambiar la propiedad activeArea de CCMenuItem. (cocos2d 2.x)

CGRect active = [someMenuItem activeArea]; 
[someMenuItem setActiveArea:CGRectMake(active.origin.x - active.size.width * 2.f, active.origin.y - active.size.height * 2.5f, active.size.width * 2.f, active.size.height * 2.f)]; 
[someMenu addChild:someMenuItem]; 
+0

Como 'activeArea' es estándar, creo que esta solución es correcta. Si usa versiones antiguas, consulte la publicación de Sébastien Dabet (http://2sa-studio.blogspot.kr/2013/01/custom-touch-area-for-ccmenuitem-in.html) y aplique un parche a su cocos2d de forma manual. – Dalinaum

+0

Bien, resuelvo el mismo problema que su código anterior. –

+0

¿Está disponible en Cocos2dx? No puedo encontrarlo – Anil

Cuestiones relacionadas