Swift 如何使touch.locationInNode()识别节点及其子节点之间的差异?

Swift 如何使touch.locationInNode()识别节点及其子节点之间的差异?,swift,sprite-kit,touchesbegan,Swift,Sprite Kit,Touchesbegan,我首先声明了两个SKSpriteNodes,handle和blade,并添加了handle作为self的子对象,blade作为handle的子对象 var handle = SKSpriteNode(imageNamed: "Handle.png") var blade = SKSpriteNode(imageNamed: "Blade.png") override func didMoveToView(view: SKView) { handle.position = CGPoin

我首先声明了两个SKSpriteNodes,handle和blade,并添加了handle作为self的子对象,blade作为handle的子对象

var handle = SKSpriteNode(imageNamed: "Handle.png")
var blade = SKSpriteNode(imageNamed: "Blade.png")

override func didMoveToView(view: SKView) {

    handle.position = CGPointMake(self.size.width / 2, self.size.height / 14)
    blade.position = CGPointMake(0, 124)

    self.addChild(Handle)
    Handle.addChild(Blade)
}
当我点击手柄时,它会打印到控制台“点击手柄”,但是当我点击刀片时,它也会打印“点击手柄”。它清楚地认识到刀片是手柄的子对象,但当我点击刀片时,它会打印“刀片被点击”,我怎么能做到这一点呢

override func touchsbegined(touchs:Set,withEvent-event:UIEvent){
用于触摸输入(触摸设置为){
let location=touch.locationInNode(自)
if(句柄.容器点(位置)){
NSLog(“单击了句柄”)
}
else if(刀片包含点(位置)){
NSLog(“单击刀片”)
}
}
}

这应该可以在不改变太多现有代码的情况下工作

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    for touch in (touches as! Set<UITouch>) {

        let locationInScene = touch.locationInNode(self)
        let locationInHandel = touch.locationInNode(Handle)

        if (Blade.containsPoint(locationInHandel)){

            NSLog("Blade was clicked")

        }
        else if (Handle.containsPoint(locationInScene)){

            NSLog("Handle was clicked")

        }

    }
}
override func touchsbegined(touchs:Set,withEvent-event:UIEvent){
用于触摸输入(触摸设置为){
让locationInScene=touch.locationInNode(自)
让LocationInHandle=触摸。locationInNode(手柄)
if(叶片包含点(位于叶片上)){
NSLog(“单击刀片”)
}
else if(Handle.containsPoint(locationInScene)){
NSLog(“单击了句柄”)
}
}
}
注意,首先检查刀片,然后检查手柄。还请注意,您必须转换接触点,以便从控制柄内部为您提供一个点

话虽如此,这将在小范围内起作用,但您可能希望为SKSpriteNode创建一个名为Handle或swarm的子类(这就是为什么您不为变量名使用第一个大写字母,它们通常只为类使用第一个大写字母),将其设置为userInteractionEnabled,然后覆盖该子类中开始的touches,查看它是否接触刀片,如果没有,您知道它接触了手柄


希望这会有所帮助并有意义。

这应该可以在不改变太多现有代码的情况下工作

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    for touch in (touches as! Set<UITouch>) {

        let locationInScene = touch.locationInNode(self)
        let locationInHandel = touch.locationInNode(Handle)

        if (Blade.containsPoint(locationInHandel)){

            NSLog("Blade was clicked")

        }
        else if (Handle.containsPoint(locationInScene)){

            NSLog("Handle was clicked")

        }

    }
}
override func touchsbegined(touchs:Set,withEvent-event:UIEvent){
用于触摸输入(触摸设置为){
让locationInScene=touch.locationInNode(自)
让LocationInHandle=触摸。locationInNode(手柄)
if(叶片包含点(位于叶片上)){
NSLog(“单击刀片”)
}
else if(Handle.containsPoint(locationInScene)){
NSLog(“单击了句柄”)
}
}
}
注意,首先检查刀片,然后检查手柄。还请注意,您必须转换接触点,以便从控制柄内部为您提供一个点

话虽如此,这将在小范围内起作用,但您可能希望为SKSpriteNode创建一个名为Handle或swarm的子类(这就是为什么您不为变量名使用第一个大写字母,它们通常只为类使用第一个大写字母),将其设置为userInteractionEnabled,然后覆盖该子类中开始的touches,查看它是否接触刀片,如果没有,您知道它接触了手柄


希望这能起到帮助并有意义。

确定用户是触摸了剑的手柄还是刀刃是相当简单的,需要注意一些。以下假设为1。当
zRotation=0
,2时,剑图像向右。剑的
主播点是(0,0.5)和3。剑(刀锋和剑柄)是单个精灵节点。将一个精灵添加到另一个精灵时,父框架的大小将扩展以包含子节点。这就是为什么无论你在哪里点击剑,你对Handle.containsPoint的测试都是正确的


下图显示了一个深灰色手柄(左侧)和浅灰色刀刃的剑精灵。围绕剑的黑色矩形代表精灵的框架,圆圈代表用户触摸的位置。标有
a
的线的长度是从接触点到剑底部的距离。我们可以测试这个距离,看看用户是否触摸了把手(如果
一个把手长度
)。当
zRotation=0
时,
a=x
因此测试是
x确定用户是否触摸了剑的手柄或刀刃,这相当简单,但有一些警告。以下假设为1。当
zRotation=0
,2时,剑图像向右。剑的
主播点是(0,0.5)和3。剑(刀锋和剑柄)是单个精灵节点。将一个精灵添加到另一个精灵时,父框架的大小将扩展以包含子节点。这就是为什么无论你在哪里点击剑,你对Handle.containsPoint的测试都是正确的


下图显示了一个深灰色手柄(左侧)和浅灰色刀刃的剑精灵。围绕剑的黑色矩形代表精灵的框架,圆圈代表用户触摸的位置。标有
a
的线的长度是从接触点到剑底部的距离。我们可以测试这个距离,看看用户是否触摸了把手(如果
一个把手长度
)。当
zRotation=0
时,
a=x
因此测试是
x,您可以通过为每个节点分配唯一的名称属性并在touchesbeent方法中检查节点的名称来进行区分。但这正是我所做的,它没有起作用。我将其中一个命名为handle,另一个命名为blade,当我点击blade时,它认为我再次点击了handleHello@Lahav。您是对的,因为它是一个子对象,您不能使用
containsPoint
,因为它基本上使用精灵的框架,并查看场景坐标系中的点是否与其子对象中的点匹配,但您需要子对象的子对象。永远不要害怕,援助就要来了!要么是我自己,要么是一个精灵
    let location = touch.locationInNode(self)
    // Check if the user touched inside of the sword's frame (see Figure 1-3)
    if (sword.frame.contains(location)) {
        // Convert the touch location from scene to sword coordinates
        let point = sword.convertPoint(location, fromNode: self)
        // Check if the user touched any part of the sword. Note that a = point.x and b = point.y
         if (fabs(point.y) < sword.size.height/2 + touchTolerance) {
             // Check if the user touched the handle
             if (point.x <= handleLength) {
                 println("touched handle")
             }
             else {
                 println("touched blade")
             }
        }
    }