且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

SKNode 从接触点缩放

更新时间:2023-02-01 13:00:11

我一直在解决同样的问题,我的解决方案如下所示.不确定这是否是***的方法,但到目前为止它似乎有效.我正在使用此代码放大和缩小具有多个 SKSpriteNode 子级的 SKNode.孩子们都根据需要使用 SKNode 移动和缩放.缩放的锚点是捏合手势的位置.场景中的父 SKScene 和其他 SKNode 不受影响.所有工作都在识别器状态 == UIGestureRecognizerStateChanged 期间进行.

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...

     }
}

以下是上面使用的辅助函数.它们来自 Ray Wenderlich 关于 Sprite Kit 的书.

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));
}