【问题标题】:Add simple animated GIF to iOS Spritekit Game?向 iOS Spritekit 游戏添加简单的动画 GIF?
【发布时间】:2014-09-10 19:39:07
【问题描述】:

我是一名初级程序员,正在使用 iOS sprite-kit 创建游戏。我有一个保存为 .gif 文件的简单动画 GIF(30 帧)。有没有一种简单的方法(几行代码可能类似于通过 UIImage 添加常规 .png)在我的游戏中显示这个 GIF?我对在 Xcode 中显示动画 GIF 进行了一些研究,其中大部分涉及导入大量类,其中大部分是我认为不需要的东西(我几乎不知道如何筛选它)。

【问题讨论】:

标签: ios objective-c animated-gif


【解决方案1】:

我认为 gif 就像动画精灵一样。所以我要做的是在for循环中将gif作为纹理添加到SKSpriteNode中,然后使用SKAction.repeatActionForever()告诉它在设备上运行。 老实说,我对此也很陌生。我只是想给出我最好的答案。这是用 Swift 编写的,但我认为翻译成 Objective-C 并不难。

var gifTextures: [SKTexture] = [];

    for i in 1...30 {
        gifTextures.append(SKTexture(imageNamed: "gif\(i)"));
    }

    gifNode.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(gifTextures, timePerFrame: 0.125)));

【讨论】:

  • 但动画 GIF 是单个文件,而在您的代码中,您假设一系列单帧图像文件。
【解决方案2】:

Michael Choi 的回答将使您成功。剩下的就是从 gif 文件中取出各个帧。这是我的做法(在 Swift 中):

func load(imagePath: String) -> ([SKTexture], TimeInterval?) {
    guard let imageSource = CGImageSourceCreateWithURL(URL(fileURLWithPath: imagePath) as CFURL, nil) else {
        return ([], nil)
    }

    let count = CGImageSourceGetCount(imageSource)
    var images: [CGImage] = []

    for i in 0..<count {
        guard let img = CGImageSourceCreateImageAtIndex(imageSource, i, nil) else { continue }
        images.append(img)
    }

    let frameTime = count > 1 ? imageSource.delayFor(imageAt: 0) : nil

    return (images.map { SKTexture(cgImage: $0) }, frameTime)
}

extension CGImageSource { // this was originally from another SO post for which I've lost the link. Apologies.

    func delayFor(imageAt index: Int) -> TimeInterval {
        var delay = 0.1

        // Get dictionaries
        let cfProperties = CGImageSourceCopyPropertiesAtIndex(self, index, nil)
        let gifPropertiesPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 0)
        if CFDictionaryGetValueIfPresent(cfProperties, Unmanaged.passUnretained(kCGImagePropertyGIFDictionary).toOpaque(), gifPropertiesPointer) == false {
            return delay
        }

        let gifProperties: CFDictionary = unsafeBitCast(gifPropertiesPointer.pointee, to: CFDictionary.self)

        // Get delay time
        var delayObject: AnyObject = unsafeBitCast(
            CFDictionaryGetValue(gifProperties,
                                 Unmanaged.passUnretained(kCGImagePropertyGIFUnclampedDelayTime).toOpaque()),
            to: AnyObject.self)
        if delayObject.doubleValue == 0 {
            delayObject = unsafeBitCast(CFDictionaryGetValue(gifProperties,
                                                             Unmanaged.passUnretained(kCGImagePropertyGIFDelayTime).toOpaque()), to: AnyObject.self)
        }

        delay = delayObject as? TimeInterval ?? 0.1

        if delay < 0.1 {
            delay = 0.1 // Make sure they're not too fast
        }

        return delay
    }

}

请注意,我假设 gif 的每一帧都是相同的长度,但情况并非总是如此。

你也可以很容易地用这些图片构建一个SKTextureAtlas

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多