views:

3440

answers:

4

I'm just wondering how I might do this and hoping that somebody has done something similar. I would like for a sprite to scale as the finger remains on the screen. Any tips, general guidelines, or methods I could look at would be appreciated.

A: 

Well ... It seems that the sprite class has a scale method that lets you set its scale, as a floating-point value where 1.0 is the default ("native") scale.

You're not being very clear on how you want the sprite to scale, if it's supposed to scale to "follow" the touch, i.e. letting the user re-size the sprite by dragging, or if's just going to (for example) change its scale to notify the user the touch was registered. You need to figure these things out, and compute the desired scale you want.

unwind
A: 

When i get you right you want to scale the sprite WHILE the finger remains on the same spot without moving is that correct?

I would recommend using a Layer with the following methods:

- (BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (BOOL)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
- (BOOL)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

You could schedule an interval based action/method in ccTouchesBegan to increase the scale of your sprite (e.g increase 0.1 per second) and in ccTouchesEnded you cancel that action and set the scale back to the original value (e.g 1.0).

For scheduling have a look at that method (found in any Class extending CocosNode):

-(void) schedule: (SEL) s;

Christian
+1  A: 

Define the action you want performed, in this case ... a ScaleBy (as you want it relative to the current scale, not a definitive scale). When the touch is received, RepeatForever this action until the touch ends, then stop the action.

If you wanted to implement an upper bounds so that the item does not grow beyond a certain point, then your ScaleBy would then be a ScaleTo with the upper bound set as the target scale. You will have to play around with the durations to get the feeling that your looking for, however. Too fast, too slow, etc ... those are up to you.

- (void)ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
   UITouch* touch = [touches anyObject];
   CGPoint location = [[[Director sharedDirector] convertCoordinate: touch.location];
   CGRect particularSpriteRect = CGMakeRect(particularSprite.position.x, particularSprite.position.y, particularSprite.contentSize.width, particularSprite.contentSize.height);
   if(CGRectContainsPoint(particularSpriteRect, location)) {
     // scale by 1.25 every 0.25 second while finger touching
     id a = [RepeatForever actionWithAction: [ScaleBy actionWithDuration: 0.25 scale: 1.25];
     [a setTag: YOUR_TAG];
     [particularSprite runAction: a];
     return kEventHandled;
   }
}

- (void)ccTouchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
  // code to determine correct finger/touch releases omitted
  [particularSprite stopActionByTag: YOUR_TAG];
}
David Higgins
A: 

I just implemented a zoom-in/zoom-out on touch using cocos2D and SpaceManager. The already accepted answer looks fine but I wanted to show how you could go about this if you are already using SpaceManager.

Note: this snippet zooms in and out in one swoop. The already accepted answer can be looked at to see how you would modify this to only do the zoom out upon release.

This is how I did it:

#pragma mark touch
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
  NSLog(@"Touched began");
  CGPoint position = [touch locationInView: [touch view]];
  CGPoint positionLocal =[[CCDirector sharedDirector] convertToGL: position];

  cpShape *touchedShape = [smgr getShapeAt:positionLocal];
  if (touchedShape != nil) {
    NSLog(@"something was touched");
    cpCCSprite *cpCCSOwner = (cpCCSprite *) touchedShape->data;
    // Let's do 'pulse' special effect on whatever we just touched, just to give the user some feedback        
    cpFloat originalScale_ = cpCCSOwner.scale;
    CCFiniteTimeAction *zoomAction = [CCScaleTo actionWithDuration:0.1f scale:originalScale_ * 1.2f];// zoom in
    CCFiniteTimeAction *shrinkAction = [CCScaleTo actionWithDuration:0.1f scale:originalScale_];// zoom out
    CCSequence *actions = [CCSequence actions:zoomAction, shrinkAction, nil];// zoom in, then zoom out
    [cpCCSOwner runAction:actions];// now

    // Since I just grabbed the object, it should stop moving
    cpCCSOwner.shape->body->v = cpvzero;

    // Let's keep track of what we are touching.
    cpCCSpriteTouched = cpCCSOwner; //<- I just added this to the class, you'll need something more sophisticated from non-trivial cases


  } else {
    NSLog(@"nothing was actually touched - you missed");    
    cpCCSpriteTouched = nil;
  }
  return YES;   
}
JJ Rohrer