Ios SKEmiterNode搭配AVAudioPlayer,提供音乐视觉效果
请有人帮忙 我想让我的SKEmiterNode的规模(意思是大小)越来越大,越来越小,以适应我使用AVAudioPlayer在应用程序中内置的音乐。现在,这几乎是我为SKEmiterNode所做的一切,它看起来很棒: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
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)
}