繁体   English   中英

Swift:检测bodyAtPoint。 永远没有

[英]Swift: detecting bodyAtPoint. Always nil

我挣扎,发现我为什么不能检测bodyAtPoint与SpriteKit。 bodyAtPoint总是返回nil ,即使看起来我总是点击精灵节点。

这是代码:

...

let spaceship = SKSpriteNode(color: UIColor.blueColor(), size: CGSizeMake(100, 100))

override func didMoveToView(view: SKView) {
    /* Setup your scene here */

    var borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
    self.physicsBody = borderBody
    self.physicsBody.friction = 0.0
    self.physicsWorld.gravity = CGVectorMake(0.0, 0.0)

    spaceship.name = "spaceship"
    spaceship.position = CGPointMake(400, 300)

    var bodySize = CGSizeMake(spaceship.size.width / 1.15, spaceship.size.height / 1.15);
    spaceship.physicsBody = SKPhysicsBody(rectangleOfSize: bodySize)

    spaceship.physicsBody.dynamic = false
    spaceship.physicsBody.restitution = 1.0
    spaceship.physicsBody.friction = 0.0
    spaceship.physicsBody.linearDamping = 0.0
    spaceship.physicsBody.allowsRotation = false

    self.addChild(spaceship)
}

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

    /* Called when a touch begins */
    super.touchesBegan(touches, withEvent: event)

    var touch : UITouch! = touches.anyObject() as UITouch
    var touchLocation : CGPoint! = touch.locationInNode(self)

    if self.physicsWorld.bodyAtPoint(touchLocation) {
        NSLog("true")
    } else {
        NSLog("false")
    }
}

...

结果:

spaceship.physicsBody输出:

<SKPhysicsBody> type:<Rectangle> representedObject:[<SKSpriteNode> name:'spaceship' texture:['nil'] position:{400, 300} size:{100, 100} rotation:0.00]

touchLocation输出:

(411.943664550781,553.014099121094)

self.physicsWorld.bodyAtPoint(touchLocation)总是:

nil

...因此条件总是返回false

谁能解释我哪里出错? 我想最终检测精灵节点上的触摸并执行操作。

编辑:

即使我简化到以下内容,我仍然总是false

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

    ...

    for touch: AnyObject in touches {
        let location = touch.locationInNode(self)

        if self.physicsWorld.bodyAtPoint(location) {
            NSLog("true")
        } else {
            NSLog("false")
        }
    }
}

...

如果要完全使用bodyAtPoint,则无法访问节点的名称。 问题是如果你想要像素完美的触摸检测 ,例如,你需要检测形状而不是alpha部分的精灵的矩形。

诀窍是使用categoryBitMask 例如,您可以将类别0x1 << 1分配给对象,然后询问其类别。 Category是一个Uint32,具有与name相同的功能,主要用于物理碰撞检测,但您可以使用它来识别physicsBody:

        let nodo = self.physicsWorld.bodyAtPoint(punto)
        if (nodo?.categoryBitMask == 0x1 << 1) {

        }

太简单! 希望它能帮到你!

非常感谢@eXhausted的答案。

诀窍是调用nodeAtPoint并访问nodeAtPoint.name。

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

    for touch: AnyObject in touches {

        let location: CGPoint! = touch.locationInNode(self)

        let nodeAtPoint = self.nodeAtPoint(location)

        if nodeAtPoint.name {
            println("NODE FOUND: \(nodeAtPoint.name)")
        } else {
            println("NULL")
        }

    }

}

当节点接近另一个具有附加粒子发射器的节点时,我遇到了类似的问题。 似乎nodeAtPoint()检测到了发射器,即使它当时被隐藏了。

我通过使用替代nodesAtPoint()并迭代遍历节点直到找到我真正想要检测的节点来解决这个问题。

如果粒子发射器将它带到堆栈的顶部,或者不想在此阶段摆弄z排序,不确定是否z顺序,在触点处找到所有触摸的节点对我有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM