在 Spritekit 中更改场景,检测按钮上的触摸

Posted

技术标签:

【中文标题】在 Spritekit 中更改场景,检测按钮上的触摸【英文标题】:Changing Scenes In Spritekit, Detecting Touches on Buttons 【发布时间】:2018-07-09 20:05:24 【问题描述】:

我正在尝试在 Spritekit 中从家庭场景更改为游戏场景。当我在模拟器中运行它时,没有过渡到 GameScene。我还添加了一个打印命令,以查看播放按钮上的触摸是否已被注册,但实际上并没有。这是代码。谢谢!

import SpriteKit

class HomeScene: SKScene 

    var playButton: SKSpriteNode?
    var gameScene: SKScene!

override func didMove(to view: SKView) 
    playButton = self.childNode(withName: "startButton") as? SKSpriteNode



override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
    if let touch = touches.first 
        let pos = touch.location(in: self)
        let node = self.atPoint(pos)

        if node == playButton 
            let transition = SKTransition.fade(withDuration: 1)
            gameScene = SKScene(fileNamed: "GameScene")
            gameScene.scaleMode = .aspectFit
            self.view?.presentScene(gameScene, transition: transition)
            print("touch")
        

    

【问题讨论】:

您不希望 playButton 是可选的,请使用 lazy var playButton = return self.childNode(withName: "startButton") as! SKSpriteNode() 。然后,第一次调用 playButton 时,它会进行搜索并记住它。如果它崩溃了,那么你知道你的场景查找播放按钮有问题,不要切换回as?试图修复它 【参考方案1】:

touchesBegan(_: with:) 方法中的touches 参数属于Set&lt;UITouch&gt; 类型,即一组触摸。如Apple Documentation for Sets 中所述,当集合中项目的顺序不是问题时,使用集合。因此,您不能假设touches 中的第一个项目是集合中的第一个触摸。知道了这一点,我建议将 HomeScene.swift 中的代码重构为以下内容:

import SpriteKit

class HomeScene: SKScene 

    private var playButton: SKSpriteNode?

    override func sceneDidLoad() 
        self.playButton = self.childNode(withName: "//starButton") as? SKSpriteNode
    

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
        for t in touches 
            self.touchDown(atPoint: t.location(in: self))
        
    

    func touchDown(atPoint pos: CGPoint) 
        let nodes = self.nodes(at: pos)

        if let button = playButton 
            if nodes.contains(button) 
                let gameScene = SKScene(fileNamed: "GameScene")
                self.view?.presentScene(gameScene)
        
    

touchDown(atPoint:) 方法完成了所有繁重的工作,touchesBegan(_: with:) 被释放以侦听触摸事件。拨打childNode(withName:)时还有一点需要注意:

在文件名开始搜索从文件层次结构的根开始的节点之前添加/。 在文件名之前添加// 开始搜索从文件层次结构的根开始的节点,然后递归地向下搜索层次结构。 在文件名前添加* 作为字符通配符,允许您搜索完全或部分未知的文件名。

【讨论】:

【参考方案2】:

我认为您应该在 touchesBegan 中使用节点的名称而不是节点本身进行比较...尝试这样的操作:

import SpriteKit

class HomeScene: SKScene 

    var playButton: SKSpriteNode?
    var gameScene: SKScene!

    override func didMove(to view: SKView) 
        playButton = self.childNode(withName: "startButton") as? SKSpriteNode

    

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
        if let touch = touches.first 
            let pos = touch.location(in: self)
            let node = self.atPoint(pos)

            if node.name == "startButton" 
                let transition = SKTransition.fade(withDuration: 1)
                gameScene = SKScene(fileNamed: "GameScene")
                gameScene.scaleMode = .aspectFit
                self.view?.presentScene(gameScene, transition: transition)
                print("touch")
            

        
    

希望对您有所帮助! :)

【讨论】:

以上是关于在 Spritekit 中更改场景,检测按钮上的触摸的主要内容,如果未能解决你的问题,请参考以下文章

在按钮 B 的触地期间触发按钮 A 上的触地

iOS11 AR场景中关于3D模型的触碰检测

SpriteKit:检测当新场景显示以后

如果使用编辑器中的场景加载,如何在 SpriteKit 中检测触摸

在spritekit swift问题中更改场景

SpriteKit Swift 2.0 游戏:跨多个场景的按钮和节点