2016-05-06 4 views
1

У меня есть SKNode на 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 

    } 
} 

ответ

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

     let touch = touches.anyObject() as UITouch! 
     let touchLocation = touch.locationInNode(self) 
     let previousLocation = touch.previousLocationInNode(self) 
     let distanceX = touchLocation.x - previousLocation.x 
     let distanceY = touchLocation.y - previousLocation.y 

     circle.position = CGPointMake(circle.position.x + distanceX, circle.position.y + distanceY) 
} 
2

Это классическая основная проблема в игровой техники.

Есть два решения ...


Первый решение: когда палец сначала идет вниз, обратите внимание на «схватывание» дельта, будучи дельта от положения объекта , пальцем.

Когда палец движется каждый раз в новое положение P, вычитать «схватывание» дельта от Р до того установки положения объекта Р.

«Это так просто»


Второе решение: каждый раз, когда палец перемещается, не беспокойтесь ни о чем с позицией P пальца.

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

(Таким образом, просто сохраняйте предыдущую позицию каждый раз, чтобы вы могли подсчитать, что некоторые системы предоставляют вам предыдущую позицию как свойство, так как это так распространено, действительно, некоторые системы просто дают вам дельта автоматически как свойство!)

Затем только переместите объект той дельтой.

"Это так просто"


Вот именно первое решение, в 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 
    } 
} 
+0

Примечание - ОП задал вопрос о p обрабатывая прикосновение в любом месте сцены (а не на спрайте). Код идентичен. Обычно у вас есть код для спрайта по спрайту, поэтому я привел примеры, подобные этому, - вы можете копировать и вставлять! :) – Fattie

Смежные вопросы