在OS X上使用NSPanGestureRecognizer拖动SKNode时闪烁

时间:2015-03-19 15:19:21

标签: macos cocoa swift sprite-kit uigesturerecognizer

今天我决定尝试添加到OS X的一些新的闪亮(iOS启发)内容:手势识别器和Sprite Kit。我已经为SKView设置了一个NSPanGestureRecognizer,我用它来拖动添加到场景中的节点。但是,在快速拖动节点时,我看到一个奇怪的闪烁。

Flicker when dragging quickly.

代码非常简单,在AppDelegate中设置所有内容,

func applicationDidFinishLaunching(aNotification: NSNotification) {
    // Insert code here to initialize your application

    // Add and scene to the view and create a root node
    hostingView.presentScene(SKScene(size: CGSize(width: 1500.0, height: 1500.0)))
    rootNode = SKNode()

    // A a red circle
    let node = SKShapeNode(circleOfRadius: 50.0)
    node.lineWidth = 5.0
    node.strokeColor = NSColor.whiteColor()
    node.fillColor = NSColor.redColor()
    node.userInteractionEnabled = true
    rootNode?.addChild(node)
    hostingView.scene?.addChild(rootNode!)

}

然后实现手势识别器的操作方法

@IBAction func panAction(sender: AnyObject) {

    // Get the location in the view from the pan gesture recogniser
    let viewPoint = (sender as NSPanGestureRecognizer).locationInView(hostingView)

    // Convert from view -> scene -> root node coordinates
    if let scene = hostingView.scene {

        let scenePoint = hostingView.convertPoint(viewPoint, toScene:scene)

        if let root = self.rootNode {

                let rootNodePoint = scene.convertPoint(scenePoint, toNode: root)
                let node = root.nodeAtPoint(rootNodePoint)
                node.position = rootNodePoint
                println("Drag to point:", NSStringFromPoint(scenePoint))
                return
            }
        }

    println("Node was nil.")
}

如果想要运行此项目,it's on github.

1 个答案:

答案 0 :(得分:1)

当快速拖动鼠标并退出节点的边界时,nodeAtPoint:返回后台节点。这导致了闪烁(感谢@sangony)。

解决方案是使用NSGestureRecognizer's state值来区分第一次触发(NSGestureRecognizerStateBegan),更新(NSGestureRecognizerStateChanged)以及何时释放鼠标({{3}} {1}})。通过检查这些值,即使鼠标移动到节点边界之外,也可以缓存正确的节点更新。

更新的操作方法是,

NSGestureRecognizerStateEnded