【问题标题】:iOS8 SpriteKit how to do drag and drop with inertia (flick with finger)?iOS8 SpriteKit如何进行惯性拖放(用手指轻弹)?
【发布时间】:2015-03-25 15:03:38
【问题描述】:

我正在查看this drag and drop tutorial by Ray Wenderleich,它允许在屏幕上拖动精灵,但是没有重力,一旦用户抬起手指,精灵就会被固定在原位。

同时我是looking at this SpriteKit collision demo by Apple,对象之间有碰撞。

然后是this tutorial which shows how to apply impulse to sprites.

我已经把demo组合在一起了,所以我的场景有重力、边缘碰撞和弹跳,但是拖放代码仍然没有惯性。

如何将精灵的拖放行为修改为“拖放”?我正在寻找类似于滚动视图中的视图的行为 - 加速、减速和惯性。 p>

下面的代码有两种模式 - 将脉冲施加到精灵上的轻弹和改变精灵位置的拖动。我不确定如何将两个代码路径组合到

- (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]];
    }
}

【问题讨论】:

  • 一种选择是存储拖动节点的当前位置和最后位置。根据 x 和 y 的变化,您将知道节点被拖动的速度,并且可以在 touchesEnded 后相应地应用脉冲强度。
  • 您好,不确定这是否是您要查找的内容,但请在此处查看我的答案stackoverflow.com/q/28245653/2158465

标签: ios sprite-kit drag-and-drop physics


【解决方案1】:

当平移识别器将状态更改为结束时,您需要应用脉冲。在拖动过程中使物理体静止也是一个好主意。最好的地方是touchesBegan,因为它是最快的。这是我的 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
        }
    }
}

【讨论】:

    猜你喜欢
    • 2021-07-03
    • 2010-12-22
    • 2011-09-30
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 2011-02-24
    相关资源
    最近更新 更多