Sprite-Kit for UIPinchGestureRecognizer Scaling Issues

I have been working on this code for a long time, but it just feels like a step forward and two steps back. I hope someone can help me.

I work with the Sprite Kit, so I have a Scene file that controls the rendering, user interface, and touch controls. I have a SKNode that works like a camera like this:

_world = [[SKNode alloc] init];
[_world setName:@"world"];
[self addChild:_world];

I use UIGestureRecognizer, so I add the ones I need:

_panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePanFrom:)];
[[self view] addGestureRecognizer:_panRecognizer];
_pinchRecognizer = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinch:)];
[[self view] addGestureRecognizer:_pinchRecognizer];

Panning is working fine, but not really. Pinching is a real problem. The idea of ​​pinching is to capture a point in the center of the screen, convert that point to the world of the node, and then move to it while zooming. Here is a way to pinch:

-(void) handlePinch:(UIPinchGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateBegan) {
    _tempScale = [sender scale];
}
if (sender.state == UIGestureRecognizerStateChanged) {
    if([sender scale] > _tempScale) {
        if (_world.xScale < 6) {
            //_world.xScale += 0.05;
            //_world.yScale += 0.05;
            //[_world setScale:[sender scale]];
            [_world setScale:_world.xScale += 0.05];

            CGPoint screenCenter = CGPointMake(_initialScreenSize.width/2, _initialScreenSize.height/2);
            CGPoint newWorldPoint = [self convertTouchPointToWorld:screenCenter];

            //crazy method why does this work
            CGPoint alteredWorldCenter = CGPointMake(((newWorldPoint.x*_world.xScale)*-1), (newWorldPoint.y*_world.yScale)*-1);

            //why does the duration have to be exactly 0.3 to work
            SKAction *moveToCenter = [SKAction moveTo:alteredWorldCenter duration:0.3];
            [_world runAction:moveToCenter];
        }
    } else if ([sender scale] < _tempScale) {
        if (_world.xScale > 0.5 && _world.xScale > 0.3){
            //_world.xScale -= 0.05;
            //_world.yScale -= 0.05;
            //[_world setScale:[sender scale]];
             [_world setScale:_world.xScale -= 0.05];

            CGPoint screenCenter = CGPointMake(_initialScreenSize.width/2, _initialScreenSize.height/2);
            CGPoint newWorldPoint = [self convertTouchPointToWorld:screenCenter];

            //crazy method why does this work
            CGPoint alteredWorldCenter = CGPointMake(((newWorldPoint.x*_world.xScale - _initialScreenSize.width)*-1), (newWorldPoint.y*_world.yScale - _initialScreenSize.height)*-1);

            SKAction *moveToCenter = [SKAction moveTo:alteredWorldCenter duration:0.3];
            [_world runAction:moveToCenter];
        }
    }
}
if (sender.state == UIGestureRecognizerStateEnded) {
    [_world removeAllActions];
}
}

, - , , . . , , , - . node , (, ). . ​​ 0,3, . , . , . , , . , ( , , ), , . !

+4
1

.

fooobar.com/questions/492926/...

, , "" , , .

, .

...

// instance variables of MyScene.
SKNode *_mySkNode;
UIPanGestureRecognizer *_panGestureRecognizer;

- (void)didMoveToView:(SKView *)view
{
    _panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanFrom:)];
    [[self view] addGestureRecognizer:_panGestureRecognizer];
}

- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer
{
    if (recognizer.state == UIGestureRecognizerStateBegan) {

        [recognizer setTranslation:CGPointZero inView:recognizer.view];

    } else if (recognizer.state == UIGestureRecognizerStateChanged) {

        CGPoint translation = [recognizer translationInView:recognizer.view];
        translation = CGPointMake(-translation.x, translation.y);

        _mySkNode.position = CGPointSubtract(_mySkNode.position, translation);

        [recognizer setTranslation:CGPointZero inView:recognizer.view];

    } else if (recognizer.state == UIGestureRecognizerStateEnded) {

        // No code needed for panning.
    }
}

, . .

SKT_INLINE CGPoint CGPointAdd(CGPoint point1, CGPoint point2) {
    return CGPointMake(point1.x + point2.x, point1.y + point2.y);
}

SKT_INLINE CGPoint CGPointSubtract(CGPoint point1, CGPoint point2) {
    return CGPointMake(point1.x - point2.x, point1.y - point2.y);
}
+9

Source: https://habr.com/ru/post/1530356/


All Articles