SpriteKit SKScene 初始化

SpriteKit SKScene initialization

提问人:Bob 提问时间:10/2/2023 最后编辑:Luca AngelettiBob 更新时间:10/28/2023 访问量:28

问:

我正在尝试将我的游戏转换为使用 Codable 而不是 NSCoding,但我在如何初始化游戏场景方面遇到了问题。

我有一个名为 GameScene 的类和 2 个名为 TownScene 和 WorldScene 的子类。GameScene 除了保存 TownScene 和 WorldScene 使用的一些共享变量和函数外,实际上什么都不做。

class GameScene: SKScene, SKPhysicsContactDelegate, UIGestureRecognizerDelegate {

    var isGamePaused: Bool = false
    var destinationMap: String = ""
    var mapEntrance: String = ""
    var dynamicEntities = Set<GKEntity>()
    var staticEntities = Set<StaticEntity>()
    //some other variables

    //some shared functions
}

final class WorldScene: GameScene, Codable {
    enum CodingKeys: String, CodingKey {
        case dynamicEntities
        case staticEntities
        case destinationMap
        case obstacleGraph
        case obstacles
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    required init(from decoder: Decoder) throws {
        super.init()
        
        let values = try decoder.container(keyedBy: CodingKeys.self)
        destinationMap = try values.decode(String.self, forKey: .destinationMap)
        dynamicEntities = try! values.decode(Set<EnemyEntity>.self, forKey: .dynamicEntities)
        staticEntities = try! values.decode(Set<StaticEntity>.self, forKey: .staticEntities)
        //......decoding more stuffs
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(destinationMap, forKey: .destinationMap)
        try container.encode(staticEntities, forKey: .staticEntities)
        //---some other encodings
    }
}

我可以毫无问题地对 WorldScene 进行编码,但是我的问题是,每当加载场景时,它总是调用 WorldScene 的:

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

如何让它调用required init(from decoder: Decoder)?因为这是我进行所有解码以恢复保存场景的地方。还是我看错了方向?

提前感谢您的任何意见。

Swift Sprite-Kit 初始化 可编码

评论

0赞 Fault 10/3/2023
在ViewController的什么位置创建这些场景对象?如果是这样,也发布该代码片段。也许您没有正确调用解码器 init

答:

1赞 Luca Angeletti 10/28/2023 #1

如果使用 Xcode 👇 定义场景

enter image description here

它创建一个文件 👇sks

enter image description here

然后,当您加载场景调用时

GameScene(fileNamed: "GameScene")

SpriteKit 使用传统技术将文件解码为对象。sksGameSceneNSCoding

这就是 SpriteKit 的构建方式,您无法更改它,因为文件使用该格式。sksNSCoding

可编纂

但是,您可以做的是使用 将实例编码为值。GameSceneDataEncodable

let gameScene: GameScene = ...
let data = try JSONEncoder().encode(gameScene)

现在,您可以将该值解码为实例。dataGameScene

let decodedGameScene = try JSONDecoder().decode(GameScene.self, from: data)

当然,要做到这一点,你需要正确地使你的GameScene类符合协议。Codable