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

SpriteKit场景出现幽灵按钮及SKPhysicsContactDelegate不触发问题求助

问题根因及修复方案

1. 按钮文字重叠问题

该问题由两个叠加性错误导致:

  • 每次调用addStartButton时,仅移除了startButton的父级引用,但没有清空startButton自身已有的子节点,多次调用后startButton上会叠加多个SKLabelNode,自然出现文字重叠
  • 你定义的gameScene是计算属性,SwiftUI视图每次重绘时都会生成一个全新的NyonindoGameScene实例,多个场景实例叠加在SpriteView上,也会导致多个按钮重合显示

修复步骤:

  • 把gameScene从计算属性改成存储属性,只初始化一次,避免重复生成场景实例:
// 替换原有的gameScene计算属性
lazy var gameScene: SKScene = {
    let scene = NyonindoGameScene(
        size: CGSize(
            width: UIScreen.main.bounds.width,
            height: UIScreen.main.bounds.height
        )
    )
    scene.viewModel = self.viewModel
    scene.scaleMode = .aspectFill
    return scene
}()
  • 修改addStartButton方法,添加新标签前先清空startButton的所有子节点:
func addStartButton(text: String) {
    startButton.removeFromParent()
    // 新增:清空原有子节点,避免文字叠加
    startButton.removeAllChildren()
    let startButtonLabel = SKLabelNode(text: text)
    startButtonLabel.fontName = SKFont.bold
    startButtonLabel.fontSize = 40.0
    startButtonLabel.fontColor = UIColor.white
    startButtonLabel.position = CGPoint(x: 0, y: -12)
    startButton.position = CGPoint(x:self.frame.midX, y:self.frame.midY)
    startButton.zPosition = 3
    startButton.addChild(startButtonLabel)
    addChild(startButton)
}

2. 碰撞逻辑失效问题

该问题和场景重复生成直接相关:之前每次触发视图重绘都会生成新的场景实例,你看到的按钮点击是触发了顶层新场景的逻辑,但新场景要么没有正确设置physicsWorld.contactDelegate,要么和旧场景的物理系统运行冲突,导致碰撞回调无法触发。

修复步骤:

  • 确认NyonindoGameScene的didMove(to view: SKView)方法中,仅调用一次physicsWorld.contactDelegate = self,不要重复设置
  • 确认场景内的物理体categoryBitMask、contactTestBitMask设置正确,没有因为局数重置被修改
  • 完成上述存储属性的修改后,全局只存在一个场景实例,物理代理的设置不会被重复覆盖,碰撞问题会同步解决

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 10:06:02