1

好的,我已经阅读了一些关于这个的帖子(例如UIImageView Gestures (Zoom, Rotate) Question),但我似乎无法解决我的问题。

我有以下设置:一个 SKScene、一个 SKNode _backgroundLayer 和 9 个 SKSpriteNode,它们是构成背景并附加到 _backgroundLayer 的图块。由于这 9 个图块构成一个 3x3 正方形并且它们非常大,因此我需要能够放大并查看将位于这 9 个背景图像之上的其他 SKSpriteNode。

有两个问题:1)当我捏放大或缩小时,它似乎是从 _backgroundLayer 的位置(0,0)而不是从触摸位置放大/缩小。

2)我添加了一些边界,以便用户无法滚动出 9 个背景图像。一般来说,它有效。但是,如果我放大然后移到 9 个背景图像的顶部,然后缩小边界条件,就会发疯,用户可以看到背景图像之外的黑色空间。我需要一种方法来限制用户可以根据他所在的位置进行的缩小量。

有任何想法吗?谢谢!

我在下面包含我的代码:

 #import "LevelSelectScene.h"
    #import "TurtleWorldSubScene.h"

    @interface LevelSelectScene ()
    @property (nonatomic, strong) SKNode *selectedNode;
    @end

    @implementation LevelSelectScene
    {
     SKNode *_backgroundLayer;
    }

    -(id)initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]) {
        /* Setup your scene here */

        _backgroundLayer = [SKNode node];
        _backgroundLayer.name = @"backgroundLayer";

        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {

            [_backgroundLayer setScale:0.76];

        } else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone && IS_WIDESCREEN) {

        } else {
            [_backgroundLayer setScale:0.36];
        }


        [self addChild:_backgroundLayer];

        SKTexture *backgroundTexture = [SKTexture textureWithImageNamed:@"levelSelect"];
        int textureID = 0;

        for (int i = 0; i<3; i++) {
            for (int j = 0; j<3; j++) {

                SKSpriteNode *background = [SKSpriteNode spriteNodeWithTexture:backgroundTexture];

                background.anchorPoint = CGPointZero;
                background.position = CGPointMake((background.size.width)*i, (background.size.height)*j);
                background.zPosition = 0;
                background.name = [NSString stringWithFormat:@"background%d", textureID];

                textureID++;

                [_backgroundLayer addChild:background];
            }
        }

        [TurtleWorldSubScene displayTurtleWorld:self];

    }
    return self;
}

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

    //UITapGestureRecognizer * tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    //  [self.view addGestureRecognizer:tapRecognizer];
    UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)];
    [[self view] addGestureRecognizer:pinchGestureRecognizer];
}

- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer {

    if (recognizer.state == UIGestureRecognizerStateBegan) {

        CGPoint touchLocation = [recognizer locationInView:recognizer.view];

        touchLocation = [self convertPointFromView:touchLocation];

        SKNode *node = [self nodeAtPoint:touchLocation];

        _selectedNode = node;

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

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

        CGPoint initialPosition = CGPointAdd(_backgroundLayer.position, translation);

        _backgroundLayer.position = [self boundLayerPos:initialPosition];
        [recognizer setTranslation:CGPointZero inView:recognizer.view];

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

        float scrollDuration = 0.2;
        CGPoint velocity = [recognizer velocityInView:recognizer.view];
        CGPoint pos = [_backgroundLayer position];
        CGPoint p = CGPointMultiplyScalar(velocity, scrollDuration);

        CGPoint newPos = CGPointMake(pos.x + p.x, pos.y - p.y);
        newPos = [self boundLayerPos:newPos];

        [_backgroundLayer removeAllActions];
        SKAction *moveTo = [SKAction moveTo:newPos duration:scrollDuration];
        [moveTo setTimingMode:SKActionTimingEaseOut];
        [_backgroundLayer runAction:moveTo];

    }
}

- (void)handlePinch:(UIPinchGestureRecognizer *) recognizer
{

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {


        if(_backgroundLayer.xScale*recognizer.scale < 0.76) {

            //SKSpriteNode *backgroundTile = (SKSpriteNode *)[_backgroundLayer childNodeWithName:@"background0"];

            [_backgroundLayer setScale:0.76];
        } else if(_backgroundLayer.xScale*recognizer.scale > 2) {
            [_backgroundLayer setScale:2.0];
        } else {
            [_backgroundLayer runAction:[SKAction scaleBy:recognizer.scale duration:0]];
        }

    } else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone && IS_WIDESCREEN) {

    } else {
        if(_backgroundLayer.xScale*recognizer.scale < 0.36) {
            [_backgroundLayer setScale:0.36];
        } else if(_backgroundLayer.xScale*recognizer.scale > 2) {
            [_backgroundLayer setScale:2.0];
        } else {
            [_backgroundLayer runAction:[SKAction scaleBy:recognizer.scale duration:0]];
        }
    }

    recognizer.scale = 1;
}

- (CGPoint)boundLayerPos:(CGPoint)newPos {
    SKSpriteNode *backgroundTile = (SKSpriteNode *)[_backgroundLayer childNodeWithName:@"background0"];

    CGPoint retval = newPos;
    retval.x = MIN(retval.x, 0);
    retval.x = MAX(retval.x, -(backgroundTile.size.width*_backgroundLayer.xScale*3)+self.size.width);
    retval.y = MIN(retval.y, 0);
    retval.y = MAX(retval.y, -(backgroundTile.size.height*_backgroundLayer.xScale*3)+self.size.height);

    return retval;
}
4

0 回答 0