请有人帮忙!
我想让我的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
}
知道我怎么能这样做吗?我查看了一些教程,例如:https://www.raywenderlich.com/36475/how-to-make-a-music-visualizer-in-ios
然而,我不能完全理解它,因为他们使用的是发射器层和它在Obj-C中,并且也对你很棒的人可能拥有的任何其他想法感兴趣!
答案 0 :(得分:0)
警告:以下代码尚未经过测试。如果有效,请告诉我。
首先,看起来您正在使用SpriteKit,因此您可以在display: table
方法SKScene
中放置更改发射器比例所需的代码,该方法会自动被调用为update:
。 1}}。
基本上,您需要做的就是根据CADisplayLink
频道的音量更新update:
方法中的发射器比例。请注意,音频播放器可能有多个通道正在运行,因此您需要平均每个通道的平均功率。
...首先
AVAudioPlayer
初始化音频播放器后设置此项,以便监控频道的级别。
接下来,在更新方法中添加类似的内容。
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
}
用于将分贝的功率转换为更合适的百分比表示。这个方法可以这样声明......
getIntensityFromPower
此转换的算法取自此StackOverflow响应https://stackoverflow.com/a/16192481/3222419。