如何在 SpriteKit 中从 Web API 加载精灵表
How to load sprite sheets from web API in SpriteKit
我是 SpriteKit 的新手,我的问题是如何从网络加载 sprite 表 API。
目前,我有一个 API returns 一个大的 PNG 图像,其中包含所有精灵表,以及一个 json 关于单个帧信息的图像。 (文件和 json 由 TexturePacker 生成) API 看起来像这样:
格式就像一个 .atlasc
文件夹,其中包含一个大图像和一个 plist (XML) 文件。
我正在考虑下载图像和plist文件并将其保存在磁盘中以便加载。但是,SKTextureAtlas.init(named: String)
只能从应用程序包中加载。
总之,我想在运行时从网络加载精灵动画。
我可以控制 API,所以我可以更新 API 来实现我的目标。
我想到的方法是下载 image
,创建一个 sourceTexture
,例如:let sourceTexture = SKTexture(image: image)
然后使用json
中的frame
信息通过方法init(rect rect: CGRect, inTexture texture: SKTexture)
创建单独的纹理
示例代码为:
var textures: [SKTexture] = []
let sourceTexture = SKTexture(image: image)
for frame in spriteSheet.frames {
let rect = CGRect(x: frame.frame.origin.x / spriteSheet.size.width,
y: 1.0 - (frame.frame.size.height / spriteSheet.size.height) - (frame.frame.origin.y / spriteSheet.size.height),
width: frame.frame.size.width / spriteSheet.size.width,
height: frame.frame.size.height / spriteSheet.size.height)
let texture = SKTexture(rect: rect, inTexture: sourceTexture)
textures.append(texture)
}
和@Honghao Zhang 的回答基本一致,但是第一眼看的时候有点迷糊
所以我为以后的读者分享我的代码片段。
编码愉快:)
func getSpriteTextures() -> [SKTexture]? {
guard let spriteSheet = loadSpriteJson(name: "sprite_json_file", codable: SpriteJson.self) else { return nil }
let sourceImage = UIImage(named: "sprite_img_file.png")!
let sourceTexture = SKTexture(image: sourceImage)
var textures: [SKTexture] = []
let sourceWidth = spriteSheet.meta.size.w
let sourceHeight = spriteSheet.meta.size.h
let orderedFrameImgNames = spriteSheet.frames.keys.sorted()
for frameImgName in orderedFrameImgNames {
let frameMeta = spriteSheet.frames[frameImgName]!
let rect = CGRect(x: frameMeta.frame.x / sourceWidth,
y: 1.0
- (frameMeta.sourceSize.h / sourceHeight)
- (frameMeta.frame.y / sourceHeight),
width: frameMeta.frame.w / sourceWidth,
height: frameMeta.frame.h / sourceHeight)
let texture = SKTexture(rect: rect, in: sourceTexture)
textures.append(texture)
}
return textures
}
我是 SpriteKit 的新手,我的问题是如何从网络加载 sprite 表 API。
目前,我有一个 API returns 一个大的 PNG 图像,其中包含所有精灵表,以及一个 json 关于单个帧信息的图像。 (文件和 json 由 TexturePacker 生成) API 看起来像这样:
格式就像一个 .atlasc
文件夹,其中包含一个大图像和一个 plist (XML) 文件。
我正在考虑下载图像和plist文件并将其保存在磁盘中以便加载。但是,SKTextureAtlas.init(named: String)
只能从应用程序包中加载。
总之,我想在运行时从网络加载精灵动画。
我可以控制 API,所以我可以更新 API 来实现我的目标。
我想到的方法是下载 image
,创建一个 sourceTexture
,例如:let sourceTexture = SKTexture(image: image)
然后使用json
中的frame
信息通过方法init(rect rect: CGRect, inTexture texture: SKTexture)
示例代码为:
var textures: [SKTexture] = []
let sourceTexture = SKTexture(image: image)
for frame in spriteSheet.frames {
let rect = CGRect(x: frame.frame.origin.x / spriteSheet.size.width,
y: 1.0 - (frame.frame.size.height / spriteSheet.size.height) - (frame.frame.origin.y / spriteSheet.size.height),
width: frame.frame.size.width / spriteSheet.size.width,
height: frame.frame.size.height / spriteSheet.size.height)
let texture = SKTexture(rect: rect, inTexture: sourceTexture)
textures.append(texture)
}
和@Honghao Zhang 的回答基本一致,但是第一眼看的时候有点迷糊
所以我为以后的读者分享我的代码片段。
编码愉快:)
func getSpriteTextures() -> [SKTexture]? {
guard let spriteSheet = loadSpriteJson(name: "sprite_json_file", codable: SpriteJson.self) else { return nil }
let sourceImage = UIImage(named: "sprite_img_file.png")!
let sourceTexture = SKTexture(image: sourceImage)
var textures: [SKTexture] = []
let sourceWidth = spriteSheet.meta.size.w
let sourceHeight = spriteSheet.meta.size.h
let orderedFrameImgNames = spriteSheet.frames.keys.sorted()
for frameImgName in orderedFrameImgNames {
let frameMeta = spriteSheet.frames[frameImgName]!
let rect = CGRect(x: frameMeta.frame.x / sourceWidth,
y: 1.0
- (frameMeta.sourceSize.h / sourceHeight)
- (frameMeta.frame.y / sourceHeight),
width: frameMeta.frame.w / sourceWidth,
height: frameMeta.frame.h / sourceHeight)
let texture = SKTexture(rect: rect, in: sourceTexture)
textures.append(texture)
}
return textures
}