Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios SKEmiterNode搭配AVAudioPlayer,提供音乐视觉效果_Ios_Swift_Animation_Avaudioplayer_Skemitternode - Fatal编程技术网

Ios SKEmiterNode搭配AVAudioPlayer,提供音乐视觉效果

Ios SKEmiterNode搭配AVAudioPlayer,提供音乐视觉效果,ios,swift,animation,avaudioplayer,skemitternode,Ios,Swift,Animation,Avaudioplayer,Skemitternode,请有人帮忙 我想让我的SKEmiterNode的规模(意思是大小)越来越大,越来越小,以适应我使用AVAudioPlayer在应用程序中内置的音乐。现在,这几乎是我为SKEmiterNode所做的一切,它看起来很棒: beatParticle?.position = CGPoint(x: self.size.width * 0.5, y: self.size.height * 0.5) var beatParticleEffectNode = SKEffectNode() beatPartic

请有人帮忙

我想让我的SKEmiterNode的规模(意思是大小)越来越大,越来越小,以适应我使用AVAudioPlayer在应用程序中内置的音乐。现在,这几乎是我为SKEmiterNode所做的一切,它看起来很棒:

beatParticle?.position = CGPoint(x: self.size.width * 0.5, y: self.size.height * 0.5)

var beatParticleEffectNode = SKEffectNode()
beatParticleEffectNode.addChild(beatParticle!)
self.addChild(beatParticleEffectNode)
所有的查找都在.sks文件中完成

这里是我在一个连续循环中调用“updateBeatParticle”函数的地方,这样我就可以把我的代码放在这里,使粒子的比例(意思是大小)随着音乐越来越大

var dpLink : CADisplayLink?

dpLink = CADisplayLink(target: self, selector: "updateBeatParticle")
dpLink?.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)

func updateBeatParticle(){
//Put code here
}
你知道我该怎么做吗?我看了一些教程,例如:


然而,我不能完全理解它,因为他们在Obj-C中使用了发射层和它,而且我还对你们这些优秀的人可能有的任何其他想法感兴趣

警告:以下代码尚未测试。请让我知道它是否有效。

首先,看起来您正在使用SpriteKit,因此您可以将更改发射器比例所需的代码放入
SKScene
方法
update:
,该方法几乎与
CADisplayLink
一样频繁地自动调用

基本上,您需要做的就是根据
AVAudioPlayer
的通道数量,在
update:
方法中更新发射器比例。请注意,音频播放器可能有多个频道在运行,因此您需要平均每个频道的平均功率

首先

player.meteringEnabled = true 
在初始化音频播放器后设置此选项,以便它监视频道的音量

接下来,在更新方法中添加类似的内容

override func update(currentTime: CFTimeInterval) {

    var scale: CGFloat = 0.5

    if audioPlayer.playing { // Only do this if the audio is actually playing
        audioPlayer.updateMeters() // Tell the audio player to update and fetch the latest readings

        let channels = audioPlayer.numberOfChannels

        var power: Float = 0
        // Loop over each channel and add its average power
        for i in 0..<channels {
            power += audioPlayer.averagePowerForChannel(i)
        }
        power /= Float(channels) // This will give the average power across all the channels in decibels

        // Convert power in decibels to a more appropriate percentage representation
        scale = CGFloat(getIntensityFromPower(power))

    }

    // Set the particle scale to match
    emitterNode.particleScale = scale
}
此转换的算法取自此StackOverflow响应

// Will return a value between 0.0 ... 1.0, based on the decibels
func getIntensityFromPower(decibels: Float) -> Float {
    // The minimum possible decibel returned from an AVAudioPlayer channel
    let minDecibels: Float = -160
    // The maximum possible decibel returned from an AVAudioPlayer channel
    let maxDecibels: Float = 0

    // Clamp the decibels value
    if decibels < minDecibels {
        return 0
    }
    if decibels >= maxDecibels {
        return 1
    }

    // This value can be adjusted to affect the curve of the intensity
    let root: Float = 2

    let minAmp = powf(10, 0.05 * minDecibels)
    let inverseAmpRange: Float = 1.0 / (1.0 - minAmp)
    let amp: Float = powf(10, 0.05 * decibels)
    let adjAmp = (amp - minAmp) * inverseAmpRange

    return powf(adjAmp, 1.0 / root)
}