Это классическая основная проблема в игровой техники.
Есть два решения ...
Первый решение: когда палец сначала идет вниз, обратите внимание на «схватывание» дельта, будучи дельта от положения объекта , пальцем.
Когда палец движется каждый раз в новое положение 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
}
}
Примечание - ОП задал вопрос о p обрабатывая прикосновение в любом месте сцены (а не на спрайте). Код идентичен. Обычно у вас есть код для спрайта по спрайту, поэтому я привел примеры, подобные этому, - вы можете копировать и вставлять! :) – Fattie