SpriteKit SKScene 初始化

问题描述 投票:0回答:1

我正在尝试将我的游戏转换为使用 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 initialization
1个回答
0
投票

如果您使用 Xcode 定义场景👇

它会创建一个

sks
文件 👇

然后当你加载场景时

SKScene(fileNamed: "GameScene")

SpriteKit 使用传统的

sks
技术将
GameScene
文件解码为
NSCoding
对象。

这就是 SpriteKit 的构建方式,您无法更改它,因为

sks
文件使用
NSCoding
格式。

可编码

但是,您可以做的是使用

GameScene
Data
实例编码为
Encodable
值。

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

现在您可以将数据值解码为

GameScene
实例。

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

当然,要执行此操作,您需要使您的 GameScene 类正确符合

Codable
协议。

© www.soinside.com 2019 - 2024. All rights reserved.