如何使用velocity来拖动和释放对象

Nig*_*man 0 touch sprite-kit swift

我正在使用Xift,使用swift,我希望能够用手指触摸球,将其拖到屏幕上,然后当我拿起手指时,它应该保持它在拖动.我已经尝试在阵列中记录触摸的最后5个位置,然后根据球的当前位置和5帧前的位置之间的位置差来计算速度,但它经常以奇数角度和速度射出.有一个更好的方法吗?提前感谢任何建议.

0x1*_*41E 5

用速度拖动和释放精灵可以通过以下方式实现

首先,a struct存储触摸数据

struct TouchInfo {
    var location:CGPoint
    var time:NSTimeInterval
}
Run Code Online (Sandbox Code Playgroud)

声明SKScene子类属性

var selectedNode:SKSpriteNode?
var history:[TouchInfo]?
Run Code Online (Sandbox Code Playgroud)

touchesBegan

  1. 保存用户触摸的精灵
  2. 保存触摸事件数据

SWIFT代码:

let touch = touches.anyObject() as UITouch
let location = touch.locationInNode(self)
let node = self.nodeAtPoint(location)
if (node.name == "player") {
    // Step 1
    selectedNode = node as? SKSpriteNode;
    // Stop the sprite
    selectedNode?.physicsBody?.velocity = CGVectorMake(0,0)
    // Step 2: save information about the touch
    history = [TouchInfo(location:location, time:touch.timestamp)]
}
Run Code Online (Sandbox Code Playgroud)

touchesMoved

  1. 如果在touchesBegan中选择了一个精灵,请将精灵移动到新位置
  2. 保存触摸事件数据

SWIFT代码:

let touch = touches.anyObject() as UITouch
let location = touch.locationInNode(self)
if (selectedNode != nil) {
    // Step 1. update sprite's position
    selectedNode?.position = location
    // Step 2. save touch data at index 0
    history?.insert(TouchInfo(location:location, time:touch.timestamp),atIndex:0)
}
Run Code Online (Sandbox Code Playgroud)

touchesEnded

  1. 计算最后一次触摸和当前触摸的x和y差异
  2. 找出触摸事件之间的时差
  3. 计算并保持x和y中速度分量的总和
  4. 创建一个速度矢量并将其应用于精灵
  5. 取消选择节点

SWIFT代码:

if let history = history, history.count > 1 && selectedNode != nil {
    var vx:CGFloat = 0.0
    var vy:CGFloat = 0.0
    var previousTouchInfo:TouchInfo?
    // Adjust this value as needed
    let maxIterations = 3
    var numElts:Int = min(history.count, maxIterations)
    // Loop over touch history
    for index in 0..<numElts {
        let touchInfo = history[index]
        let location = touchInfo.location
        if let previousTouch = previousTouchInfo {
            // Step 1
            let dx = location.x - previousTouch.location.x
            let dy = location.y - previousTouch.location.y
            // Step 2
            let dt = CGFloat(touchInfo.time - previousTouch.time)
            // Step 3
            vx += dx / dt
            vy += dy / dt
        }
        previousTouchInfo = touchInfo
    }
    let count = CGFloat(numElts-1)
    // Step 4
    let velocity = CGVectorMake(vx/count,vy/count)
    selectedNode?.physicsBody?.velocity = velocity
}
// Step 5
selectedNode = nil
history = nil
Run Code Online (Sandbox Code Playgroud)