如何在 SpriteKit 中从 Web API 加载精灵表

Posted

技术标签:

【中文标题】如何在 SpriteKit 中从 Web API 加载精灵表【英文标题】:How to load sprite sheets from web API in SpriteKit 【发布时间】:2016-11-25 09:34:34 【问题描述】:

我是 SpriteKit 的新手,我的问题是如何从 Web API 加载精灵表。

目前,我有一个 API 返回一个大的 PNG 图像,其中包含所有精灵表和一个关于单个帧信息的 json。 (文件和json由TexturePacker生成)API如下:

该格式就像一个.atlasc 文件夹,其中包含一个大图像和一个plist (XML) 文件。

我正在考虑下载图像和 plist 文件并将其保存在磁盘中以进行加载。但是,SKTextureAtlas.init(named: String) 只能从 app bundle 加载。

总之,我想在运行时从网络加载精灵动画。

我可以控制 API,因此我可以更新 API 以实现我的目标。

【问题讨论】:

这就是扩展存在的原因,使用 SKTextureAtlas(dictionary:string:AnyObject) 作为你指定的 init 你的意思是我需要让 API 返回单个图像,我下载它们并用init(dictionary: [String : AnyObject]) 初始化一个SKTextureAtlas 不,您下载其他图集(纹理打包器图集),然后通过代码从中制作单独的纹理,并使用我说的方法放置它们。 SkTexture 允许您从储藏室纹理中提取纹理,因此您将主图像加载为纹理,然后基于 json,将个体提取出来 【参考方案1】:

我想出的方法是下载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)
    

【讨论】:

【参考方案2】:

与@Honghao Zhang 的回答基本相同,但乍一看我对整个结构有点困惑。

所以我将我的代码 sn-p 分享给以后的读者。

编码愉快:)

    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 中从 Web API 加载精灵表的主要内容,如果未能解决你的问题,请参考以下文章

如何在asp.net核心中从客户端调用web api方法?

在 SpriteKit/Swift 中从数组中删除元素

如何在 iOS 中从 UIView 转移到 SKScene

我需要在 iOS 应用程序中从 SpriteKit GameViewController 转换为常规视图控制器(Objective-C)

我们如何在 powerBI 中从 graphql api 获取数据

在 MVC Web Api 4 Beta 中从 Json 中删除 Null 属性