【问题标题】:How to synchronize textures animation and sound in SpriteKit如何在 SpriteKit 中同步纹理动画和声音
【发布时间】:2021-05-17 01:17:22
【问题描述】:

我正在使用 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 的回调。

如果您想尝试和我一起完成这项工作,或者您对如何做有想法,请发表评论。

谢谢:)

【问题讨论】:

  • 类似下面的东西会起作用 - 让 sequence = SKAction.sequence([walkinganimation,playsound])。只是为了把握好时机。
  • 我尝试使用组、序列,但声音播放一次,动画继续。我希望能够在每次帧变化时播放声音。
  • 你的动画有多少帧?
  • 这取决于动画但我想抽象这部分

标签: ios swift sprite-kit skaction


【解决方案1】:

试试这个:

  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)

【讨论】:

  • 我不想指定每个帧,但我想我必须!我会努力回来的,谢谢
  • 我认为唯一的其他方法是为您的动画找到/创建匹配的声音。
【解决方案2】:

所以,现在我要这样做:

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

【讨论】:

  • 我会使用这段代码,直到找到更好的方法!
【解决方案3】:

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

        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
    }

【讨论】:

  • 如果要改变动画速度,需要用Audacity之类的软件来改变音频文件的长度吗?我遇到的另一个问题是我想每 2 帧播放一次声音,因为在步行动画的每一帧中脚都不会接触地面
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-10
  • 1970-01-01
相关资源
最近更新 更多