如何在 SpriteKit 中同步纹理动画和声音

How to synchronize textures animation and sound in SpriteKit

我正在使用 SpriteKit 创建一个 RPGGameKit 来帮助我开发 iOS 游戏。现在我的播放器可以移动了,我添加了动画和音频系统。

我 运行 关于同步纹理和声音的问题。就像我的球员走路时的一步。

let atlas = SKTextureAtlas(named: "Walk")
let textures = atlas.getTextures() // I created an extension that returns textures of atlas

let walkingAnimation = SKAction.animate(with: textures, timePerFrame: 1)

因此,walkingAnimation 将循环遍历纹理并每 1 秒更改一次。

现在,我想在纹理变化时播放走路的声音。

我查看了 SKAction 和 SpriteKit 文档,但没有针对此 SKAction 的回调。

如果你想和我一起完成这件事,或者你有如何做的想法,请发表评论。

谢谢:)

试试这个:

  let frame1 = SKAction.setTexture(yourTexture1)
  let frame2 = SKAction.setTexture(yourTexture2)
  let frame3 = SKAction.setTexture(yourTexture3)
  //etc

  let sound = SKAction.playSoundFileNamed("soundName", waitForCompletion: false)
  let oneSecond = SKAction.wait(forDuration: 1)
  let sequence = SKAction.sequence([frame1,sound,oneSecond,frame2,sound,oneSecond,frame3,sound,oneSecond])

  node.run(sequence)

所以,现在我要这样做 :

let textures = SKTextureAtlas(named: "LeftStep").getTextures()
var actions = [SKAction]()

for texture in textures {
    
    let group = SKAction.group([
        SKAction.setTexture(texture),
        SKAction.playSoundFileNamed("Step.mp3", waitForCompletion: false)
    ])

    let sequence = SKAction.sequence([
        group,
        SKAction.wait(forDuration: 0.5)
    ])

    actions.append(sequence)

}

self.node.run(SKAction.repeatForever(SKAction.sequence(actions)))

感谢@StefanOvomate

我发现自己处于同样的情况,目前我正在执行以下操作。根据我在文档和网上看到的内容,唯一的方法是创建音频文件长度以匹配纹理动画的一个旋转。

        let walkAtlas = global.playerWalkAtlas
        var walkFrames: [SKTexture] = []
        
        let numImages = walkAtlas.textureNames.count
        for i in 1...numImages {
            let texture = "walk\(i)"
            walkFrames.append(walkAtlas.textureNamed(texture))
        }
        walking = walkFrames
        isWalking = true
        
        animateMove()
    }
 
    func animateMove(){
        let animateWalk = SKAction.animate(with: walking, timePerFrame: 0.05)
        let soundWalk = global.playSound(sound: .walkSound)
        
        let sequence = SKAction.sequence([soundWalk, animateWalk])
        
        self.run(SKAction.repeatForever(sequence),withKey: "isMoving")
    }
    
    func stopMoving(){
        self.removeAction(forKey: "isMoving")
        isWalking = false
    }