You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保当前SKScene完全加载后再使用GamePad Controller操作?

解决tvOS中SKScene切换过快导致的交互失效问题

1. 基于SKScene生命周期的"就绪"判断

SKScene的didMove(to view:)方法是场景完全加载并添加到视图后的回调,作用和jQuery的$(document).ready()一致。你可以在游戏场景中添加标志位,仅当场景就绪后才响应手柄输入:

class GameScene: SKScene {
    private var isSceneReady = false
    
    override func didMove(to view: SKView) {
        super.didMove(to: view)
        // 执行游戏初始化操作(棋子创建、资源加载等)
        setupGamePieces()
        
        // 标记场景已就绪
        isSceneReady = true
    }
    
    override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
        guard isSceneReady else { return }
        
        for press in presses {
            if press.type == .menu {
                // 切换场景前立即停止音效
                stopAllSoundEffects()
                switchToMenuScene()
            } else if press.type == .select {
                // 处理棋子移动逻辑
                moveGamePieces()
            }
        }
    }
    
    private func stopAllSoundEffects() {
        // 停止所有音效播放示例
        self.removeAction(forKey: "backgroundMusic")
        // 若使用AVAudioPlayer,调用对应的player.stop()方法
    }
}

2. 全局控制输入可用性

在GameViewController中维护一个全局开关,切换场景时禁用输入,直到目标场景就绪后再启用:

class GameViewController: UIViewController {
    var canHandleInput = true
    
    func switchToScene(_ scene: SKScene) {
        // 切换场景前禁用输入
        canHandleInput = false
        
        guard let skView = self.view as? SKView else { return }
        skView.presentScene(scene)
    }
}

在游戏场景的didMove(to view:)中通知ViewController启用输入:

override func didMove(to view: SKView) {
    super.didMove(to: view)
    setupGamePieces()
    
    if let vc = view.window?.rootViewController as? GameViewController {
        vc.canHandleInput = true
    }
}

手柄事件处理时先检查全局开关:

override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
    guard let vc = view.window?.rootViewController as? GameViewController, vc.canHandleInput else { return }
    
    // 后续按键逻辑处理...
}

3. 场景切换时的音效强制停止

确保在触发场景切换的瞬间就停止所有音效,避免音效残留或干扰后续场景:

private func switchToMenuScene() {
    stopAllSoundEffects()
    
    let menuScene = MenuScene(size: self.size)
    if let vc = view.window?.rootViewController as? GameViewController {
        vc.switchToScene(menuScene)
    }
}

内容的提问来源于stack exchange,提问作者user22530416

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 13:31:05