缩放SKNode时不一致

6

我创建了自己的解决方案,可以在不缩放整个场景的情况下对特定的SKNode进行缩放,它似乎大部分按照我的预期工作,但有两个显著的例外,希望在这里得到帮助。首先,这是代码(该控制语句位于touchesMoved方法中):

 if (touches.count == 2) {
        // this means there are two fingers on the screen
        NSArray *fingers = [touches allObjects];
        CGPoint fingOneCurr = [fingers[0] locationInNode:self];
        CGPoint fingOnePrev = [fingers[0] previousLocationInNode:self];
        CGPoint fingTwoCurr = [fingers[1] locationInNode:self];
        CGPoint fingTwoPrev = [fingers[1] previousLocationInNode:self];

        BOOL yPinch = fingOneCurr.y > fingOnePrev.y && fingTwoCurr.y < fingTwoPrev.y;
        BOOL yUnpinch = fingOneCurr.y < fingOnePrev.y && fingTwoCurr.y > fingTwoPrev.y;

        BOOL xPinch = fingOneCurr.x > fingOnePrev.x && fingTwoCurr.x < fingTwoPrev.x;
        BOOL xUnpinch = fingOneCurr.x < fingOnePrev.x && fingTwoCurr.x > fingTwoPrev.x;

        if (xUnpinch | yUnpinch) {
            if (YES) NSLog(@"This means an unpinch is happening");
            mapScale = mapScale +.02;
            [map setScale:mapScale];
        }

        if (xPinch | yPinch) {
            if (YES) NSLog(@"This means a pinch is happening");
            mapScale = mapScale - .02;
            [map setScale:mapScale];
        }
    }

现在的问题是:
  1. 有时候缩放和取消缩放效果不正确,我无法确定具体出现问题的情况,有时缩放变成了取消缩放,反之亦然。

  2. 当SKNode被缩放时,虽然尺寸发生了改变,但是效果并不总是像我期望的那样平滑,存在一些抖动,让人感到很烦恼。

请问有谁能给这个方法提出改进建议吗?谢谢!

尝试使用捏合手势识别器并使用其比例属性,无需重新发明轮子。 - CodeSmile
我的理解是捏合手势识别器无法放置在SKNode上。 - zeeple
你可能需要对想要缩放的节点进行子类化,然后添加捏合手势识别器? - DogCoffee
你可以使用识别器与视图一起使用,确切地说是self.scene.view。 - CodeSmile
@LearnCocos2D 我已经尝试过(现在正在尝试)在SKNode的子类中使用pinch recognizer,将其添加到self.scene.view中,但没有成功。userInteractionEnabled设置为YES。您是否成功地在SKNode中使用了手势识别器?我觉得它应该可以工作,但我一直没成功。在场景中完成很容易,我希望更深入节点的实现也同样简单,但迄今为止还没有成功。 - Ben Kane
你的原始代码有时会在你期望捏合时放开(或反之亦然),这是因为你设置了“scaleTo”值,而Smick的答案使用了“scaleBy”版本。因此,在原始代码中,如果你进行了大捏合,将比例设置为3.0,但在随后的捏合中,你稍微缩小到2.0,那么“scaleTo”代码将把它视为从3.0减少到2.0。在Smick的答案中使用scaleBy,第一次捏合会增加3.0,第二次捏合会再增加2.0。 - Thunk
1个回答

8
这将解决您的问题,感谢Steffen提供的提示。
- (void)didMoveToView:(SKView *)view
{
    UIPinchGestureRecognizer *precog = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)];
    [self.scene.view addGestureRecognizer:precog];
}

- (void)handlePinch:(UIPinchGestureRecognizer *) recognizer
{
    //NSLog(@"Pinch %f", recognizer.scale);
    //[_bg setScale:recognizer.scale];
    [_bg runAction:[SKAction scaleBy:recognizer.scale duration:0]];
    recognizer.scale = 1;
}

1
这比我想出来的好多了。谢谢! - zeeple
我喜欢这个解决方案,但是我遇到了一个问题,希望有人能帮忙解决。捏合缩放功能可以正常工作,但是捏合动作的锚点似乎总是在左下角或右上角,结果导致主角(英雄节点)最终消失在屏幕外。有没有办法在捏合/缩放期间保持主角节点在屏幕中心? - zeeple
缩放不应该改变精灵的位置。 - DogCoffee
缩放不会改变精灵相对于地图的位置。因此,随着地图越来越大,自然而然地屏幕上可以显示的地图越来越少,英雄也会随之增长。如果它在滑出屏幕的地图部分上,那么当缩放完成时,用户需要移动地图以重新找到英雄。我希望英雄精灵成为缩放的焦点,这样英雄就始终在屏幕上。这有意义吗? - zeeple
我曾经遇到过一个类似的问题,我的精灵总是向上/右或向下/左移动到屏幕外。问题出在我在地图中分配子节点的位置。地图确实是从它的中心开始增长的。但是,我开始将所有的子节点从0,0到1024,1024放置在相对于地图中心的右上象限中。因此,当地图缩放时,所有的子节点都会向上和向右滑动,离开屏幕。一旦我将地图瓦片从-512,-512到512,512放置,并将英雄放在0,0处,英雄就固定了,其他子节点在缩放时向相等的方向移动。 - Thunk
如果地图的锚点不是0,0,而是屏幕中央,这样做是否会得到一个类似甚至等效的解决方案?我还没有尝试过这个,但希望很快有时间回头再看一下。 - zeeple

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接