iOS8 SpriteKit, как сделать перетаскивание с инерцией (щелчок пальцем)?

Я смотрю на это руководство по перетаскиванию Рэя Вендерлейха, оно позволяет перетаскивать спрайты на экран, однако гравитации нет, и спрайты остаются закрепленными на месте, когда пользователь поднимает палец.

В то же время я смотрю на демонстрацию столкновения SpriteKit от Apple, в которой есть столкновения между объектами.

Тогда есть этот урок, который показывает, как применить импульс к спрайтам.

Я объединил демонстрации вместе, поэтому моя сцена имеет гравитацию, столкновение краев и подпрыгивание, но код перетаскивания все еще не имеет инерции.

Как я могу изменить поведение перетаскивания в "перетаскивание" для спрайтов? Я ищу поведение, похожее на представление в виде прокрутки - ускорение, замедление и инерция.

Код ниже имеет два режима - щелчок, который применяет импульс к спрайту и перетаскивание, которое изменяет местоположение спрайта. Я не уверен, как объединить два пути к коду

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

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

    touchLocation = [self convertPointFromView:touchLocation];

    if (recognizer.state == UIGestureRecognizerStateBegan) {

        [self selectNodeForTouch:touchLocation];

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




        SKNode* node = [self selectNodeForTouch:touchLocation];

        //this is the flick gesture - pings the 
         double angle = atan2(touchLocation.y-node.position.y,touchLocation.x-node.position.x);
        [node.physicsBody applyImpulse:CGVectorMake(20*cos(angle), 20*sin(angle))];

        //CGPoint translation = [recognizer translationInView:recognizer.view];
 //       translation = CGPointMake(translation.x, -translation.y);
 //       [self panForTranslation:translation];
 //       [recognizer setTranslation:CGPointZero inView:recognizer.view];

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



    }
}

Вот код перетаскивания:

- (void)panForTranslation:(CGPoint)translation {
    CGPoint position = [_selectedNode position];
    if([[_selectedNode name] isEqualToString:kAnimalNodeName]) {
        [_selectedNode setPosition:CGPointMake(position.x + translation.x, position.y + translation.y)];
    } else {
        CGPoint newPos = CGPointMake(position.x + translation.x, position.y + translation.y);
        [_background setPosition:[self boundLayerPos:newPos]];
    }
}

1 ответ

Вы должны применить импульс, когда средство распознавания панорамы меняет состояние на завершенное. Это также хорошая идея сделать физическое тело статичным во время перетаскивания. Лучшее место в штрихах началось, потому что оно самое быстрое. Вот пример моего кода в Swift.

func handlePan(panGestureRecognizer recognizer:UIPanGestureRecognizer) {
        let touchLocationView = recognizer.location(in: recognizer.view)
        let touchLocationScene = self.convertPoint(fromView: touchLocationView)

        switch recognizer.state {
        case .began:
            let canditateNode = self.touchedNode(touchLocationScene)
            if let name = canditateNode.name, name.contains(kMovableNode) {
                self.selectedNode = canditateNode
            }
        case .changed:
            let translation = recognizer.translation(in: recognizer.view)
            if let position = self.selectedNode?.position {
                self.selectedNode?.position = CGPoint(x: position.x + translation.x, y: position.y - translation.y)
                recognizer.setTranslation(CGPoint.zero, in: recognizer.view)
            }
        case .ended:
            self.selectedNode?.physicsBody?.isDynamic = true;
            let velocity = recognizer.velocity(in: recognizer.view)
            self.selectedNode?.physicsBody?.applyImpulse(CGVector(dx: velocity.x, dy: -velocity.y))
            self.selectedNode = nil
        default:
            break
        }
    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            NSLog("touchesBegan")
            if let touch = touches.first {
                let touchLocationScene = touch.location(in: self)
                let canditateNode = self.touchedNode(touchLocationScene)
                if let name = canditateNode.name, name.contains(kMovableNode) {
                    self.selectedNode = canditateNode
                    self.selectedNode?.physicsBody?.isDynamic = false
                }
            }
        }
Другие вопросы по тегам