Swift 如何检测节点上的触摸

Swift 如何检测节点上的触摸,swift,sprite-kit,uitouch,touchesbegan,Swift,Sprite Kit,Uitouch,Touchesbegan,我有一个每1秒在屏幕上生成一个球的应用程序。现在,我想让用户触摸这些球,让它们从父母那里消失。据我所知,我必须通过触摸开始设置触摸功能,我这样做了,以下是我的代码: override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { for touch: AnyObject in touches{ let positionOfTouch = touch.location

我有一个每1秒在屏幕上生成一个球的应用程序。现在,我想让用户触摸这些球,让它们从父母那里消失。据我所知,我必须通过触摸开始设置触摸功能,我这样做了,以下是我的代码:

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch: AnyObject in touches{
        let positionOfTouch = touch.location(in: self)
        enumerateChildNodes(withName: "BALL") { (node: SKNode, nil) in
            if positionOfTouch == node.position {
                print("just touched the ball")
            }
            else{
                print("error")
            }
        }
    }
你能帮我吗?因为我是新加入swift的,所以我也想得到一些关于这种触摸检测和一般触摸的解释——apple doc很差

您正在将精确的接触点与节点的精确位置进行比较,这两个位置不太可能相同

if positionOfTouch == node.position {
相反,您需要测试用户的触摸是否足够接近球的位置

一个选项是使用SKNode的contains函数,它将为您处理这个问题

if node.contains(positionOfTouch) {
旁注:您可能希望使用SKSpriteNode而不是SKShapeNode,因为SKShapeNode在SpriteKit中的性能很差。

您正在将精确的接触点与节点的精确位置进行比较,这两个位置不太可能相同

if positionOfTouch == node.position {
相反,您需要测试用户的触摸是否足够接近球的位置

一个选项是使用SKNode的contains函数,它将为您处理这个问题

if node.contains(positionOfTouch) {

旁注:您可能希望使用SKSpriteNode而不是SKShapeNode,因为SKShapeNode在SpriteKit中的性能很差。

每次触摸屏幕时,您都会在所有球之间循环,以查看是否触摸其中一个球。如果你有50个球在屏幕上,它会通过所有的球来查看你是否在触摸1。这不是判断你是否触摸到1的有效方法

有很多方法可以做到这一点,但我会做的是处理球类内部的接触。这样你就不必知道你是否碰到了一个球,可能是哪个球

尽我所能解释协议目前看来可能有点多,但你学习和理解协议的速度越快,你的生活就会越好

在本例中,我们将使用协议来设置 球节点类。协议是一组用户定义的规则,必须 后跟您指定的符合该协议的任何类。 在我的示例中,我声明一个类要符合 BallNodeDelegate协议它必须包含didClick函数。当你 在游戏场景后添加BallNodeLegate,您将声明 类将符合该协议。所以如果在游戏场景中你做到了 没有didClick功能,它将导致错误。所有这些都放进去了 这样,您就可以轻松地在您的 BallNode实例和游戏场景类,无需通过 围绕每个球节点对游戏场景的引用。每个球节点 然后有一个代理游戏场景,你可以传回 信息发送至

在BallNode类中,确保有isUserInteraction=true

在BallNode类之外,创建一个将触摸信息发送回游戏场景的协议

protocol BallNodeDelegate: class {
    func didClick(ball: BallNode)
}
在BallNode类中创建委托变量

weak var delegate: BallNodeDelegate!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    self.delegate?.didClick(ball: self)
}
移动球节点类开始接触的球

weak var delegate: BallNodeDelegate!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    self.delegate?.didClick(ball: self)
}
在游戏场景中,当你创建一个球时,确保你设置了它的代理

let ball = BallNode()
ball.delegate = self
在游戏场景中添加鸟巢。func来处理单击

func didClick(ball: BallNode) {
    print("clicked ball")
}

每次触摸屏幕时,你都会在所有球之间循环,以查看是否触摸其中一个球。如果你有50个球在屏幕上,它会通过所有的球来查看你是否在触摸1。这不是判断你是否触摸到1的有效方法

有很多方法可以做到这一点,但我会做的是处理球类内部的接触。这样你就不必知道你是否碰到了一个球,可能是哪个球

尽我所能解释协议目前看来可能有点多,但你学习和理解协议的速度越快,你的生活就会越好

在本例中,我们将使用协议来设置 球节点类。协议是一组用户定义的规则,必须 后跟您指定的符合该协议的任何类。 在我的示例中,我声明一个类要符合 BallNodeDelegate协议它必须包含didClick函数。当你 在游戏场景后添加BallNodeLegate,您将声明 类将符合该协议。所以如果在游戏场景中你做到了 没有didClick功能,它将导致错误。所有这些都放进去了 这样,您就可以轻松地在您的 BallNode实例和游戏场景类,无需通过 围绕每个球节点对游戏场景的引用。每个球节点 然后有一个代理游戏场景,你可以传回 信息发送至

在BallNode类中,确保有isUserInteraction=true

在BallNode类之外,创建一个将触摸信息发送回游戏场景的协议

protocol BallNodeDelegate: class {
    func didClick(ball: BallNode)
}
铬 在BallNode类中创建委托变量

weak var delegate: BallNodeDelegate!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    self.delegate?.didClick(ball: self)
}
移动球节点类开始接触的球

weak var delegate: BallNodeDelegate!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    self.delegate?.didClick(ball: self)
}
在游戏场景中,当你创建一个球时,确保你设置了它的代理

let ball = BallNode()
ball.delegate = self
在游戏场景中添加鸟巢。func来处理单击

func didClick(ball: BallNode) {
    print("clicked ball")
}


请看一下在SKNode上定义的nodesat:CGPoint,以检索被触摸位置的节点列表。不过,您需要使用convertPointfromView在视图坐标和场景坐标之间进行转换。文档和。

查看在SKNode定义的nodesat:CGPoint,以检索触摸位置的节点列表。不过,您需要使用convertPointfromView在视图坐标和场景坐标之间进行转换。文档和。

此处列出了一些可选选项:此处列出了一些可选选项:关于您侧注:SpriteKit性能差是什么意思?如果场景中同时有大量形状节点,则功能较弱的设备的帧速率会较低。其实我现在不在电脑前,我会尽快检查的。Tnx!关于你旁注:你说SpriteKit的性能差是什么意思?如果你在场景中同时有很多形状节点,那么在功能较弱的设备上,你会得到更低的帧速率。其实我现在不在电脑前,我会尽快检查的。Tnx!你能解释一下为什么要使用协议吗?我刚在apple doc上读到这篇文章,但我真的不明白它的目的。我确实在我的答案中添加并编辑了它,希望能帮助你们理解protocolswow!太棒了!非常感谢你!你有关于代表的任何指导/解释吗?还有一件事,我真的不明白你在“ball.delegate=self”这行中做了什么,那“self”属于哪里?self是你的游戏场景。这就是将这两个类绑定在一起的原因。你能解释一下为什么要使用协议吗?我刚在apple doc上读到这篇文章,但我真的不明白它的目的。我确实在我的答案中添加并编辑了它,希望能帮助你们理解protocolswow!太棒了!非常感谢你!你有关于代表的任何指导/解释吗?还有一件事,我真的不明白你在“ball.delegate=self”这行中做了什么,那“self”属于哪里?self是你的游戏场景。这就是将这两个类绑定在一起的原因