1

I have implemented zoom/pinch on my SKScene with the selected answer in this thread:

Zooming an SKNode inconsistent

I am now attempting to get the hero character to stay centered (smoothly) during a pinch or zoom action because if I don't, the heroNode will disappear off the screen quickly. I have a centerHero method which I can call when I want, and it works quite well, but when I call this method at the end of the pinch handler the effect is very, very jerky. Here is the pinch handler:

- (void)handlePinch:(UIPinchGestureRecognizer *) recognizer
{
    [map runAction:[SKAction scaleBy:recognizer.scale duration:0]];
    recognizer.scale = 1;

    // While zooming/pinching, make sure hero is centered:
    [self centerHero];
}

and here is the center hero method:

- (void)centerHero
{
    CGFloat centerX = self.view.bounds.size.width/2;
    CGFloat centerY = self.view.bounds.size.height/2;

    CGFloat heroX = [self.heroNode parent].position.x;
    CGFloat heroY = [self.heroNode parent].position.y;

    CGPoint heroPoint = CGPointMake(heroX, heroY);
    CGPoint newHeroPoint = [self convertPoint:heroPoint fromNode:map];

    CGFloat newHeroX = newHeroPoint.x;
    CGFloat newHeroY = newHeroPoint.y;

    CGFloat xDiff = centerX - newHeroX;
    CGFloat yDiff = centerY - newHeroY;

    SKAction *moveBy = [SKAction moveByX:xDiff y:yDiff duration:5];
    [map runAction:moveBy];
}

Any suggestions on how to make this "auto-centering" smooth?

Community
  • 1
  • 1
zeeple
  • 5,509
  • 12
  • 43
  • 71
  • Why not make your hero a child of the map, then he'll scale and position relative with the map and you don't need to worry about reorienting him. – prototypical Nov 12 '13 at 15:07
  • I am sorry, I was unclear. The hero is a child of the map, and does scale and move with the map, but the problem is that as the map (and the hero) both grow larger, the hero, along with a great deal of the map, slides of the screen. Does that make sense? – zeeple Nov 12 '13 at 18:17
  • Put another way: The scale does not change the position of the sprite _relative to the map_. So as the map grows increasingly larger, and naturally less of it can fit on screen, the hero grows with it and if it is on a part of the map that slides off screen, then when the zoom is finished the user needs to move the map around to find the hero again. What I would like is for the hero sprite to be the focal point of the zoom so that the hero is always on screen. Does this make sense? – zeeple Nov 12 '13 at 18:21
  • Is your map made up of one big texture ? Or is it a collection of tiles or something of that nature ? – prototypical Nov 13 '13 at 22:43
  • It is a collection of tiles. And the hero moves 32 pixels at a time in any direction. – zeeple Nov 15 '13 at 00:37

1 Answers1

1

It looks as though you are scaling the map node, rather than the scene itself. When you scale the node, it will zoom to the anchor point of that node, instead of simply zooming in to the centre of the visible area.

If you scale the scene itself it should scale everything properly, e.g.:

[self runAction:[SKAction scaleBy:recognizer.scale duration:0]];

Assuming you're running this action from within the SKScene. You could also try:

[map.scene runAction:[SKAction scaleBy:recognizer.scale duration:0]];

...which would also point to the parent scene the map belongs to.

Koonga
  • 230
  • 3
  • 9
  • Thanks for the proposed answer but i actually want the zoom to be applied to only the map. There are other sprite nodes which serve as overlays, also children of the scene which i do not wish to zoom. The target of the zoom should be only the map and its children. I wonder if i should set the focal point of the map node to the center of the hero node? Ill give that a try later. – zeeple Nov 21 '13 at 19:03