SpriteKit unarchiveFromFile 不会从资产目录和图集中加载纹理
SpriteKit unarchiveFromFile does not load textures from asset catalogues and atlases
我对 SpriteKit 还是个新手,想看看我是否可以使用 Xcode 的 SKS 编辑器构建关卡。当我添加几个带有 "Spaceship.png" 纹理的精灵并构建模板应用程序时,纹理不会加载。
这是原版 OSX 游戏模板的屏幕截图,使用 Swift 作为语言,并添加了提供的 "Spaceship.png" 精灵。纹理显示良好:
这是仅对模板进行修改后构建和 运行 应用程序的结果:
调试控制台显示此警告消息:
我尝试添加一个 .atlas 文件夹,结果相同。场景只显示红色 X 图标代替精灵。如果添加的精灵只是彩色精灵,它们显示良好。前段时间我废弃了一个应用程序,我曾经在其中加载 SKScene 并将精灵资产手动添加到我的 SKScene 子 class,并且运行良好。
但是,如果我将纹理 - "Spaceship.png" 作为示例 - 移动到项目的根目录,即不在资产目录或 .atlas 文件夹中,场景加载时纹理显示良好。
这是添加到项目根目录的纹理:
这是期望的结果:
我尝试通过 enumerateChildNodesWithName(_,usingBlock)
手动将 SKS 文件中加载的资源添加到场景中,如果纹理不在项目文件夹的根目录中,我会得到相同的结果。
这是我尝试手动添加资产:
func applicationDidFinishLaunching(aNotification: NSNotification) {
/* Pick a size for the scene */
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
let sceneToBePresented = GameScene()
/* Set the scale mode to scale to fit the window */
sceneToBePresented.scaleMode = .AspectFill
sceneToBePresented.size = scene.size
/* Sprite Kit applies additional optimizations to improve rendering performance */
self.skView!.ignoresSiblingOrder = true
self.skView!.showsFPS = true
self.skView!.showsNodeCount = true
scene.enumerateChildNodesWithName("*") { node, stop in
sceneToBePresented.addChild(node.copy() as SKSpriteNode)
}
self.skView!.presentScene(sceneToBePresented)
}
}
我环顾了 SpriteKit classes - SKNode
、SKScene
、SKTexture
、SKSPriteNode
- 寻找关于路径、缓存、预加载的任何线索,或任何东西,但无法找到可以使这项工作成功的东西。
我是 运行 Xcode 6.1.1,我的目标是 10.9,我使用的语言是 Swift,尽管使用 ObjC 也是如此。这是功能还是错误?还有其他人 running/ran 遇到类似情况吗?
提前感谢您的帮助
[更新]
看起来这还没有实现 - 从资产目录加载纹理 - 因为这个 post 在开发论坛中讨论了同样的问题,他的解决方案是将资产目录重命名为与质地。本质上,我发现根文件夹中有图像文件:How do you load sprite textures from Images.xcassets when using SKS scene file,尽管我设法回滚到工作状态的早期应用程序确实从 .atlas'es 加载纹理,但我可以似乎用一个干净的模板来做!!!
[在这里回答我自己的问题]
据我所知,目前,从资产目录加载纹理 - Images.xcassets
- 而取消存档或反序列化 SKScene
文件在 OSX 上不起作用我的尝试和上面提到的 devforumns post。
然而,从图像集加载纹理是通过强制 SKTexture
加载图像来实现的。可以通过 preloadWithCompletionHandler(_:)
或 preloadTextures(_:, withCompletionHandler:)
方法强制或“触摸”SKTexture
,或者正如我所发现的,只需打印精灵 SKTexture
的描述即可。
为了任何可能需要进一步帮助的人的利益,这里是一个代码片段,它在解压缩 SKS 文件后预加载纹理:
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
for child in scene.children as [SKNode] {
if child is SKSpriteNode {
let sprite = child as SKSpriteNode
sprite.texture?.preloadWithCompletionHandler({ })
/* or even a simple debug log of the texture */
/* println(sprite.texture) */
}
}
/* Do your other stuff ... */
...
}
如有错误请指正。在有人这样做之前,或者 Apple 修复了 SpriteKit 在 iOS 和 OSX 之间的行为之间的差异,我不会寻找其他解决方案,并将遵循墨菲定律:
If it works, don't fix it
遵循 Salam Horani 的解决方案,对于 Swift 2.x 你还没有 "unarchiveFromFile" 所以你可以创建这样的场景:
if let gameScene = GameScene(fileNamed: "GameScene") {
// ...
}
我对 SpriteKit 还是个新手,想看看我是否可以使用 Xcode 的 SKS 编辑器构建关卡。当我添加几个带有 "Spaceship.png" 纹理的精灵并构建模板应用程序时,纹理不会加载。
这是原版 OSX 游戏模板的屏幕截图,使用 Swift 作为语言,并添加了提供的 "Spaceship.png" 精灵。纹理显示良好:
调试控制台显示此警告消息:
但是,如果我将纹理 - "Spaceship.png" 作为示例 - 移动到项目的根目录,即不在资产目录或 .atlas 文件夹中,场景加载时纹理显示良好。
这是添加到项目根目录的纹理:
这是期望的结果:
enumerateChildNodesWithName(_,usingBlock)
手动将 SKS 文件中加载的资源添加到场景中,如果纹理不在项目文件夹的根目录中,我会得到相同的结果。
这是我尝试手动添加资产:
func applicationDidFinishLaunching(aNotification: NSNotification) {
/* Pick a size for the scene */
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
let sceneToBePresented = GameScene()
/* Set the scale mode to scale to fit the window */
sceneToBePresented.scaleMode = .AspectFill
sceneToBePresented.size = scene.size
/* Sprite Kit applies additional optimizations to improve rendering performance */
self.skView!.ignoresSiblingOrder = true
self.skView!.showsFPS = true
self.skView!.showsNodeCount = true
scene.enumerateChildNodesWithName("*") { node, stop in
sceneToBePresented.addChild(node.copy() as SKSpriteNode)
}
self.skView!.presentScene(sceneToBePresented)
}
}
我环顾了 SpriteKit classes - SKNode
、SKScene
、SKTexture
、SKSPriteNode
- 寻找关于路径、缓存、预加载的任何线索,或任何东西,但无法找到可以使这项工作成功的东西。
我是 运行 Xcode 6.1.1,我的目标是 10.9,我使用的语言是 Swift,尽管使用 ObjC 也是如此。这是功能还是错误?还有其他人 running/ran 遇到类似情况吗?
提前感谢您的帮助
[更新]
看起来这还没有实现 - 从资产目录加载纹理 - 因为这个 post 在开发论坛中讨论了同样的问题,他的解决方案是将资产目录重命名为与质地。本质上,我发现根文件夹中有图像文件:How do you load sprite textures from Images.xcassets when using SKS scene file,尽管我设法回滚到工作状态的早期应用程序确实从 .atlas'es 加载纹理,但我可以似乎用一个干净的模板来做!!!
[在这里回答我自己的问题]
据我所知,目前,从资产目录加载纹理 - Images.xcassets
- 而取消存档或反序列化 SKScene
文件在 OSX 上不起作用我的尝试和上面提到的 devforumns post。
然而,从图像集加载纹理是通过强制 SKTexture
加载图像来实现的。可以通过 preloadWithCompletionHandler(_:)
或 preloadTextures(_:, withCompletionHandler:)
方法强制或“触摸”SKTexture
,或者正如我所发现的,只需打印精灵 SKTexture
的描述即可。
为了任何可能需要进一步帮助的人的利益,这里是一个代码片段,它在解压缩 SKS 文件后预加载纹理:
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
for child in scene.children as [SKNode] {
if child is SKSpriteNode {
let sprite = child as SKSpriteNode
sprite.texture?.preloadWithCompletionHandler({ })
/* or even a simple debug log of the texture */
/* println(sprite.texture) */
}
}
/* Do your other stuff ... */
...
}
如有错误请指正。在有人这样做之前,或者 Apple 修复了 SpriteKit 在 iOS 和 OSX 之间的行为之间的差异,我不会寻找其他解决方案,并将遵循墨菲定律:
If it works, don't fix it
遵循 Salam Horani 的解决方案,对于 Swift 2.x 你还没有 "unarchiveFromFile" 所以你可以创建这样的场景:
if let gameScene = GameScene(fileNamed: "GameScene") {
// ...
}