Question

The problem I encounter is that the positions of the CCLabelBMFont label and the one of the CCSprite characters composing that label seem to be different so I cannot manage the touch events...

To test more in details this issue I tried this :

    -(id)init
    {
      if ((self = [super init])
      {
        CCLabelBMFont *label = [CCLabelBMFont labelWithString:"welcome" fntFile:@"Arial.fnt"];
        CGSize size = [[CCDirector sharedDirector] winSize];
        label.position =  ccp(size.width/2, size.height/2);
        [self addChild: self.label];

        self.isTouchEnabled = YES;
      }
    return self;
    }

    -(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
      UITouch *touch = [touches anyObject];
      CGPoint touchLocation = [touch locationInView:[touch view]];
      touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];
      NSLog(@"point touched: x:%f, y:%f", touchLocation.x, touchLocation.y);

      for (CCSprite *character in [label children])
      {
        if (CGRectContainsPoint([character boundingBox], touchLocation))
        {
          [character setColor:ccRED];
        }
      }
    }

And whatever the letter of the label I touch it didn't turn red as it should.

And the reason why I think the position of the sprites composing the CCLabelBMFont and the label itself are different is that when I insert :

NSLog(@"character position: x:%f y: %f", character.position.x, character.position.y);

in the ccTouchesBegan touch handling, the position of the sprites are listed to be on the lower left corner of the screen.

So maybe I'm missing something simple but is there a way to convert the sprites position to be at the same place as the label to enable the recognition of the touches on the letters of a label?

Thanks in advance.

Was it helpful?

Solution

The position of child nodes is relative to their parent. You have to use the sprite's convertToNodeSpace or convertToWorldSpace methods to convert the position accordingly. In this case you would have to use convertToNodeSpace with touchLocation as input with each sprite before using it to test bounding box collisions.

This should fix it:

for (CCSprite *character in [label children])
{
   CGPoint touchLocationNodeSpace = [character convertToNodeSpace:touchLocation];
   if (CGRectContainsPoint([character boundingBox], touchLocationNodeSpace))
   {
      [character setColor:ccRED];
   }
}

OTHER TIPS

Thanks to your advice and with a small modification I finally managed to make it work, the offset I noticed was due to the origin of the coordinates that were used for the calculation of the bounding boxes of each characters composing the label.

So by adding :

CGRect boundingBox = [character boundingBox];
boundingBox.origin = CGPointZero;

I cleared this offset in the touches detection.

Here's the final code for the touches :

-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint touchLocation = [touch locationInView:[touch view]];
    touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];

    for (CCSprite *character in [self.label children])
    {
        CGRect boundingBox = [character boundingBox];
        boundingBox.origin = CGPointZero;
        CGPoint touchLocationNodeSpace = [character convertToNodeSpace:touchLocation];
        if (CGRectContainsPoint(boundingBox, touchLocationNodeSpace))
        {
            [character setColor:ccRED];
        }
    }
}

This does the trick for me

CGRect boundingBox = [character boundingBox];
boundingBox.origin = CGPointZero;

Do not touch your left ear with your right hand.
If I were you I would register it to a menu like this: (also it adds scale affect on the fly)

-(void)GenerateButtons
{
  CGSize s = [[CCDirector sharedDirector] winSize];
  CCLabelBMFont *myBtn=[CCLabelBMFont labelWithString:@"BLABLA" fntFile:@"comicsansms.fnt"];
  CCMenuItemLabel *lbl_=[CCMenuItemLabel itemWithLabel:shakeBtn target:self selector:@selector(myButtonPressed)];
CCMenu *menu_=[CCMenu menuWithItems:lbl_, nil];
[self addChild:menu_];
[menu_ setPosition:ccp(s.width/2,(myBtn.boundingBox.size.height))];
}

-(void)myButtonPressed{
   //do what your CCLabelBMFont should do
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top