1

わかりました、これに関するいくつかの投稿を読みました (例: UIImageView Gestures (Zoom, Rotate) Question ) が、問題を解決できないようです。

次のセットアップがあります: SKScene、SKNode _backgroundLayer、および背景を構成し、_backgroundLayer にアタッチされたタイルである 9 つの SKSpriteNodes。これらの 9 つのタイルは 3x3 の正方形を形成し、非常に大きいため、ズームインして、これらの 9 つの背景画像の上にある他の SKSpriteNode を確認できるようにする必要があります。

2 つの問題があります。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