轻弹动作和UIPanGestureRecognizer的意外结果

时间:2013-12-23 10:36:37

标签: ios objective-c uigesturerecognizer sprite-kit uipangesturerecognizer

我使用以下代码在SpriteKit SKScene中实现对sprite的轻弹,以便它们将根据手指从UIPanGestureRecognizer的动作继续在屏幕上移动和滑动。

在大多数情况下它工作正常,但是当我靠近屏幕可视区域的边缘并尝试这个手势在屏幕外轻弹精灵时,它会产生相反的效果并将精灵推回中心而不是在屏幕外。

任何人都可以告诉我为什么当精灵太靠近屏幕的边缘时,它会被推回而不是像预期的那样在屏幕外闪烁?

if (recognizer.state == UIGestureRecognizerStateEnded) {
    if ([touchedNode.name isEqualToString:@"sprite"]) {
        SKSpriteNode *touchedSprite = (SKSpriteNode *)touchedNode;
        // Calculate the length of the velocity vector (i.e. the magnitude)
        CGPoint velocity = [recognizer velocityInView:self.view];
        CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
        CGFloat slideMult = magnitude / 200;
        NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult);

        // Calculate a final point based on the above
        float slideFactor = 0.1 * slideMult;    // Increase for more of a slide
        CGPoint finalPoint = CGPointMake(recognizer.view.center.x + (velocity.x * slideFactor), recognizer.view.center.y - (velocity.y * slideFactor));

        SKAction *moveAction = [SKAction moveTo:finalPoint duration:slideFactor * 2];
        [moveAction setTimingMode:SKActionTimingEaseOut];
        [touchedSprite runAction:moveAction];
    }
}

2 个答案:

答案 0 :(得分:1)

我认为您可能忘记将CGPoint从视图转换为场景

让我们假设我们初始化我们的手势

__weak IBOutlet SKView      *skView;
...
panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[skView addGestureRecognizer:panRecognizer];

因此,如果我们想要在SpriteKit空间中触摸此手势识别器的位置,我们必须将此点从视图转换为skScene

- (void)handlePan:(UIPanGestureRecognizer*)sender{

CGPoint point = [sender locationInView:skView];
point = [skView.scene convertPointFromView:point];

// do your things here

}

答案 1 :(得分:-1)

问题在于最终CGPoint的计算基于添加UIPanGestureRecognizer的位置。在这种情况下,必须将其添加到SKView,因为SKSpriteNode不是UIView子类,因此无法添加UIPanGestureRecognizer

以上是旧计算

CGPoint finalPoint = 
 CGPointMake(recognizer.view.center.x + (velocity.x * slideFactor), 
             recognizer.view.center.y - (velocity.y * slideFactor));

以下是使用精灵节点中心作为计算基础的更改。

CGPoint finalPoint = 
 CGPointMake(touchedSprite.position.x 
              + (touchedSprite.size.width / 2) 
              + (velocity.x * slideFactor), 
             touchedNode.position.y 
              + (touchedNode.size.height / 2) 
              - (velocity.y * slideFactor));