拖动SKNode而不触摸它

时间:2016-05-06 23:27:47

标签: ios swift drag-and-drop

我在SpriteKit上有一个SKNode,我基本上希望能够在屏幕上拖动,但不必触摸它!想象一下,我在任何地方按屏幕。然后我希望我的SKNode与我的手指保持距离,这样当我拖动它时我就能看到它。

我有这个工作,但对象快速触摸。

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    for touch in touches{
        let location = touch.locationInNode(self)

        circle.position = location


    }
}


override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    for touch in touches{
        let location = touch.locationInNode(self)

        circle.position = location

    }
}

2 个答案:

答案 0 :(得分:2)

这是游戏工程中的经典基本问题。

两个解决方案......

第一个解决方案:当手指第一次下降时,请记下&#34;抓住&#34; delta,是从对象位置到手指的三角形。

当手指每次移动到新位置P时,减去&#34;抓住&#34;在将对象的位置设置为P之前从P增加。

&#34;这很简单&#34;

第二次解决方案:每次手指移动时,不要用手指的位置P来打扰。

相反,计算手指从前一帧移动的 delta

(因此,每次只需存储前一个位置,以便您可以计算出来 - 有些系统会将您之前的位置作为属性,因为它非常常见,实际上某些系统会自动将delta作为属性提供给您!)

然后只需按对象移动对象

&#34;这很简单&#34;

这正是iOS / SpriteKit中的第一个解决方案

class FingerFollower: SKSpriteNode {

    var grab: CGVector = CGVector.zero
    // "grab" is the usual term for the delta from the object
    // to where the finger "grabbed" it...

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        let t: UITouch = touches.first! as UITouch
        let l = t.location(in: parent!)

        grab = (l - position).vector
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        let t: UITouch = touches.first! as UITouch
        let loc = t.location(in: parent!)

        position = loc - grab
    }

    // NOTE this code uses the absolutely obvious overrides for
    // subtraction etc between vectors, which you will need in 100%
    // of spritekit projects (Apple forgot about them)
}

这正是iOS / SpriteKit中的第二个解决方案

class FingerFollower: SKSpriteNode {

    func setup() {

        // NOTE, you MUST have a "setup" call in your sprite subclasses;
        // apple forgot to include a "didAppear" for SKNodes
        isUserInteractionEnabled = true
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        // note that Apple do in fact include the "previous location"
        // in sprite kit touches. (In systems where they don't do that,
        // you just make a note of it each time.)

        let prev = t.previousLocation(in: parent!)
        let quickDelta = loc - prev
        position = position + quickDelta
    }
}

答案 1 :(得分:1)

protected override void OnMouseLeave(EventArgs e)
{

    if(this.ClientRectangle.Contains(this.PointToClient(Control.MousePosition)))
         return;
    else
    {
        base.OnMouseLeave(e);
    }
}