SKNode scale from the touched point

前端 未结 4 1846
孤街浪徒
孤街浪徒 2020-12-09 06:26

I have added UIPinchGestureRecognizer to my scene.view to scale my content. I actually scale the parent node where all my visible contents reside. But I have problem though

4条回答
  •  半阙折子戏
    2020-12-09 06:47

    I have been working on the same problem and my solution is shown below. Not sure if it is the best way to do it, but so far it seems to work. I'm using this code to zoom in and out of an SKNode that has several SKSpriteNode children. The children all move and scale with the SKNode as desired. The anchor point for the scaling is the location of the pinch gesture. The parent SKScene and other SKNodes in the scene are not affected. All of the work takes place during recognizer.state == UIGestureRecognizerStateChanged.

    // instance variables of MyScene.
    SKNode *_mySkNode;
    UIPinchGestureRecognizer *_pinchGestureRecognizer;
    
    - (void)didMoveToView:(SKView *)view
    {
        _pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handleZoomFrom:)];
        [[self view] addGestureRecognizer:_pinchGestureRecognizer];
    }
    
    // Method that is called by my UIPinchGestureRecognizer.
    - (void)handleZoomFrom:(UIPinchGestureRecognizer *)recognizer
    {
         CGPoint anchorPoint = [recognizer locationInView:recognizer.view];
         anchorPoint = [self convertPointFromView:anchorPoint];
    
         if (recognizer.state == UIGestureRecognizerStateBegan) {
    
             // No code needed for zooming...
    
         } else if (recognizer.state == UIGestureRecognizerStateChanged) {
    
             CGPoint anchorPointInMySkNode = [_mySkNode convertPoint:anchorPoint fromNode:self];
    
             [_mySkNode setScale:(_mySkNode.xScale * recognizer.scale)];
    
             CGPoint mySkNodeAnchorPointInScene = [self convertPoint:anchorPointInMySkNode fromNode:_mySkNode];
             CGPoint translationOfAnchorInScene = CGPointSubtract(anchorPoint, mySkNodeAnchorPointInScene);
    
             _mySkNode.position = CGPointAdd(_mySkNode.position, translationOfAnchorInScene);
    
             recognizer.scale = 1.0;
    
         } else if (recognizer.state == UIGestureRecognizerStateEnded) {
    
             // No code needed here for zooming...
    
         }
    }
    

    The following are helper functions that were used above. They are from the Ray Wenderlich book on Sprite Kit.

    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);
    }
    
    SKT_INLINE GLKVector2 GLKVector2FromCGPoint(CGPoint point) {
        return GLKVector2Make(point.x, point.y);
    }
    
    SKT_INLINE CGPoint CGPointFromGLKVector2(GLKVector2 vector) {
        return CGPointMake(vector.x, vector.y);
    }
    
    SKT_INLINE CGPoint CGPointMultiplyScalar(CGPoint point, CGFloat value) {
        return CGPointFromGLKVector2(GLKVector2MultiplyScalar(GLKVector2FromCGPoint(point), value));
    }
    

提交回复
热议问题