SpriteKit:为什么包含SKNode的点返回false

时间:2016-08-02 20:51:21

标签: ios swift sprite-kit sknode

我有一个带有userInteractionEnabled = true且触摸被覆盖的SKNode。

因为即使我将手指移出SKNode,我也会随时调用touchesEnded,我想确保触摸在SKNode内结束,只有这样我才能将其视为有效的点击。

所以我做了以下事情:

class Tile : SKNode {
  var level:Int!
  init(tileWidth: CGFloat, level: Int) {
    super.init()
    self.name = "lvlseltile"
    self.level = Int(level)
    self.userInteractionEnabled = true
    let node = SKShapeNode(rect: CGRect(x: 0, y: 0, width: tileWidth, height: tileWidth))
    node.fillColor = UIColor.grayColor()
    self.addChild(node)
    let textNode = SKLabelNode(text: String(level))
    textNode.fontSize = 24
    textNode.fontColor = UIColor.whiteColor()
    textNode.horizontalAlignmentMode = .Center
    textNode.verticalAlignmentMode = .Center
    textNode.position = CGPoint(x: tileWidth/2, y: tileWidth/2)
    self.addChild(textNode)
  }

  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

  override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    let location = touches.first?.locationInNode(self)
    if self.containsPoint(location!) {
        print("tapped tile")
    }
  }
}

由于我正在检查当前节点的位置,我从当前的SKNodes坐标系中获取相对坐标。

但是self.containsPoint总是返回FALSE。我的SKNode是40x40大,我的触摸是20x20,所以在节点的中心,但它仍然返回FALSE。

为什么?

我知道如果x&gt; 0&amp;&amp; x <= 40且y> =并且y <= 40。但这正是我对self.containsPoint的期望。我做错了什么?

1 个答案:

答案 0 :(得分:0)

SKNode的宽度和高度等于0

这就是为什么触摸结束位置总是在SKNode之外。

对于需要绘制某些内容(例如frame.sizeSKNode)的子类,SKSpriteNode的{​​{1}}值实际上大于零。

来自official docs

  

frame属性为节点的可视内容提供边界矩形,由scale和rotation属性修改。如果节点的类绘制内容,则该帧不为空。每个节点子类以不同方式确定此内容的大小。在某些子类中,节点内容的大小是显式声明的,例如在SKSpriteNode类中。在其他子类中,内容大小由类使用其他对象属性隐式计算。例如,SKLabelNode对象使用标签的消息文本和字体特征确定其内容大小。

那么,如果SKNode的区域为0,那么为什么要调用SKLabelNode

我不知道。我创建了一个测试SpriteKit项目,并将我的自定义touchesEnded添加到场景中。

SKNode

然而经过多次测试后我无法点击它(正如预期的那样,因为它有0个区域)。我不知道你是如何设法将SKNode的大小设置为40 x 40以及为什么你的 class MyNode: SKNode { override init() { super.init() userInteractionEnabled = true } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) userInteractionEnabled = true } override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { print("touchesEnded!") } } 被触发。如果你愿意,你可以给我看更多代码。