提问人:Bob 提问时间:10/2/2023 最后编辑:Luca AngelettiBob 更新时间:10/28/2023 访问量:28
SpriteKit SKScene 初始化
SpriteKit SKScene initialization
问:
我正在尝试将我的游戏转换为使用 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)?因为这是我进行所有解码以恢复保存场景的地方。还是我看错了方向?
提前感谢您的任何意见。
答:
1赞
Luca Angeletti
10/28/2023
#1
如果使用 Xcode 👇 定义场景
它创建一个文件 👇sks
然后,当您加载场景调用时
GameScene(fileNamed: "GameScene")
SpriteKit 使用传统技术将文件解码为对象。sks
GameScene
NSCoding
这就是 SpriteKit 的构建方式,您无法更改它,因为文件使用该格式。sks
NSCoding
可编纂
但是,您可以做的是使用 将实例编码为值。GameScene
Data
Encodable
let gameScene: GameScene = ...
let data = try JSONEncoder().encode(gameScene)
现在,您可以将该值解码为实例。data
GameScene
let decodedGameScene = try JSONDecoder().decode(GameScene.self, from: data)
当然,要做到这一点,你需要正确地使你的GameScene类符合协议。Codable
评论