Неожиданные результаты от щелчка и UIPanGestureRecognizer

Я использую следующий код для реализации щелчка по спрайтам в SpriteKit SKScene, чтобы они продолжали перемещаться и скользить по экрану в зависимости от движения пальца из 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];
    }
}

person Mark Reid    schedule 23.12.2013    source источник
comment
У вас есть проект, который я могу скачать, чтобы проверить это?   -  person Rahul Iyer    schedule 30.12.2013
comment
логарифмическая скорость ... щелчок начинается на экране, но движение пальца за пределы экрана отменяет распознавание жестов, и, возможно, это вернет неправильную скорость.   -  person LearnCocos2D    schedule 30.12.2013


Ответы (2)


Я думаю, что возможно, вы забыли преобразовать свою 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

}
person debris    schedule 01.01.2014
comment
Извините, я сделал это, я забыл добавить это к своему вопросу. - person Mark Reid; 03.01.2014

Проблема в том, что расчет окончательного 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));
person Mark Reid    schedule 03.01.2014