如何使用该节点的自定义 class 检测在单独场景中创建的 skspritenode 上的触摸

How to detect touches on a skspritenode created in a separate scene using a custom class of that node

所以基本上我有一个名为树的节点,我在 .sks 文件中设计了它。

我为 skspritenode 添加了自定义 class,但自定义 class 似乎并未影响节点。

我正在尝试检测节点及其子节点上的触摸。

此节点正在使用 removefromparent()addchild() 函数传输到多个场景,因此我尝试使用自定义节点而不是在每个场景上编写重复代码来检测触摸 class 去做...任何帮助将不胜感激。

注意我有 super.init 纹理功能,因为它是必要的,但我想使用已经在场景中创建的节点。

我的class代码

import SpriteKit

class tree: SKSpriteNode {

    init() {
        let texture = SKTexture(imageNamed: "tree")
        super.init(texture: texture, color: SKColor.clear, size: texture.size())
        self.isUserInteractionEnabled = true
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            print("touched!")
        }
    }



}

答案中有一个很好的解释,应该清楚您对 SKS 文件和子 classing 的想法。 关于您的代码,使用大写字母作为 class 名称是一个好习惯,在您的情况下我更喜欢使用 class Tree 而不是 class 树。 关于你的第二个问题,你可以使用 userData 将你的对象从一个场景转移到另一个场景,如下面在我的例子中所解释的:

import SpriteKit
class GameScene: SKScene {
    private var label : SKLabelNode?
    var tree : Tree!
    override func didMove(to view: SKView) {
        self.label = self.childNode(withName: "//helloLabel") as? SKLabelNode
        if let label = self.label {
            label.alpha = 0.0
            label.run(SKAction.fadeIn(withDuration: 2.0))
        }
        self.isUserInteractionEnabled = true
        tree = Tree()
        tree.name = "tree"
        addChild(tree)
        tree.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch: AnyObject in touches {
            let pointOfTouch = touch.location(in: self)
            let nodeUserTapped = atPoint(pointOfTouch)
            if nodeUserTapped.name == "tree" {
                tree.removeFromParent()
                let sceneToMoveTo = Scene2.init(size: self.size)
                sceneToMoveTo.userData = NSMutableDictionary()
                sceneToMoveTo.userData?.setObject(tree, forKey: "tree" as NSCopying)
                let gameTransition = SKTransition.fade(withDuration: 0.5)
                self.view!.presentScene(sceneToMoveTo, transition: gameTransition)

            }
        }
    }
}
class Scene2: SKScene {
    var tree:Tree!
    override func didMove(to view: SKView) {
        print("This is the scene: \(type(of:self))")
        guard let previousValue = self.userData?.value(forKey: "tree") else { return }
        if previousValue is Tree {
            tree = previousValue as! Tree
            addChild(tree)
            tree.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
        }
    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch: AnyObject in touches {
            let pointOfTouch = touch.location(in: self)
            let nodeUserTapped = atPoint(pointOfTouch)
            if nodeUserTapped.name == "tree" {
                tree.removeFromParent()
                if let sceneToMoveTo = SKScene(fileNamed: "GameScene") {
                    sceneToMoveTo.scaleMode = .aspectFill
                    sceneToMoveTo.userData = NSMutableDictionary()
                    sceneToMoveTo.userData?.setObject(tree, forKey: "tree" as NSCopying)
                    let gameTransition = SKTransition.fade(withDuration: 0.5)
                    self.view!.presentScene(sceneToMoveTo, transition: gameTransition)
                }
            }
        }
    }
}

如你所见,我在我的父 class 和我的节点中都控制了触摸,这可以通过更改自定义 [=14] 的 touchesBegan 方法来实现=] 为:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        print("touched!")
    }
    guard let parent = self.parent else { return }
    parent.touchesBegan(touches, with: event)
}

请记住,如果您想使用其他触摸方法,您也应该将此方法扩展到其他触摸方法..