制作一个简单的spritekit游戏。在AVFoundation
声音库中,我有按钮触摸声音等声音。但是这有麻烦。当听到任何按钮时,我的帧速率总是会下降。但如果我把所有的声音静音,就没有滞后。这是我的代码:
import AVFoundation
class GameAudio {
static let shared = GameAudio()
private var buttonClickSound = AVAudioPlayer()
private var completionSound = AVAudioPlayer()
private var swishSound = AVAudioPlayer()
private var gridSwishSound = AVAudioPlayer()
private let Volume: Float = 0.8
func setupSounds() {
print("GameAudio setupSounds()")
if let path = Bundle.main.path(forResource: SoundNames.ButtonClickSoundName, ofType: "mp3") {
let url = URL(fileURLWithPath: path )
do {
buttonClickSound = try AVAudioPlayer(contentsOf: url)
} catch {
print(error)
}
}
if let path = Bundle.main.path(forResource: SoundNames.CompletionSoundName, ofType: "mp3") {
let url = URL(fileURLWithPath: path)
do {
completionSound = try AVAudioPlayer(contentsOf: url)
} catch {
print(error)
}
}
if let path = Bundle.main.path(forResource: SoundNames.SwishSoundName, ofType: "mp3") {
let url = URL(fileURLWithPath: path )
do {
swishSound = try AVAudioPlayer(contentsOf: url)
} catch {
print(error)
}
}
if let path = Bundle.main.path(forResource: SoundNames.GridSwishSoundName, ofType: "mp3") {
let url = URL(fileURLWithPath: path)
do {
gridSwishSound = try AVAudioPlayer(contentsOf: url)
} catch {
print(error)
}
}
buttonClickSound.volume = Volume
completionSound.volume = Volume
swishSound.volume = Volume
gridSwishSound.volume = Volume
}
func playButtonClickSound() {
buttonClickSound.play()
}
func playCompletionSound() {
completionSound.play()
}
func playSwishSound() {
swishSound.play()
}
func playGridSwishSound() {
gridSwishSound.play()
}
}
在我的GameViewController中,我调用GameAudio.shared.setupSounds()
来预加载所有声音。
public struct Actions {
static func buttonIsTouched(_ button: SKNode, sound: Bool, completion: @escaping () -> ()) {
if button.hasActions() { return }
if sound {
GameAudio.shared.playButtonClickSound()
}
button.run(touchedButtonAction(scaleFactor: button.returnScaleFactor()), completion: completion)
}
}
class MenuNode: SKNode {
private let settings: Settings
var delegate: MenuNodeDelegate?
private let playButton = SKSpriteNode(imageNamed: SpriteNames.PlayButtonName)
private let MenuNodeTreshold: CGFloat = 12.0
init(settings: Settings) {
self.settings = settings
super.init()
setupButtons()
isUserInteractionEnabled = false
}
private func setupButtons() {
playButton.position = CGPoint(x: 0.0 - playButton.frame.size.width / 2.0 - MenuNodeTreshold / 2.0, y: 0.0)
addChild(playButton)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let location = touch.location(in: self)
if playButton.contains(location) {
Actions.buttonIsTouched(playButton as SKNode, sound: settings.sound, completion: {
self.delegate?.playButtonTouched()
})
}
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
我在游戏中使用Actions
结构进行所有操作。我有buttonTouchedAction()
,我在不同的节点中使用它。我用一个“播放”按钮从菜单中输入了一些代码。因此,例如,我在设备上运行我的游戏,它显示菜单节点,等待几秒钟并点击按钮,在我的帧速率下降之后,我有一秒钟的滞后然后场景变为游戏场景。
答案 0 :(得分:1)
我有类似的问题。我最后使用role
播放短音。
h1,w1 = imageB.shape[:2]
h2,w2 = imageA.shape[:2]
pts1 = np.float32([[0,0],[0,h1],[w1,h1],[w1,0]]).reshape(-1,1,2)
pts2 = np.float32([[0,0],[0,h2],[w2,h2],[w2,0]]).reshape(-1,1,2)
pts2_ = cv2.perspectiveTransform(pts2, H)
pts = np.concatenate((pts1, pts2_), axis=0)
# print("pts:", pts)
[xmin, ymin] = np.int32(pts.min(axis=0).ravel() - 0.5)
[xmax, ymax] = np.int32(pts.max(axis=0).ravel() + 0.5)
t = [-xmin,-ymin]
Ht = np.array([[1,0,t[0]],[0,1,t[1]],[0,0,1]]) # translate
result = cv2.warpPerspective(imageA, Ht.dot(H), (xmax-xmin, ymax-ymin))
resizedB = np.zeros((result.shape[0], result.shape[1], 3), np.uint8)
resizedB[t[1]:t[1]+h1,t[0]:w1+t[0]] = imageB
# Now create a mask of logo and create its inverse mask also
img2gray = cv2.cvtColor(result,cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 0, 255, cv2.THRESH_BINARY)
kernel = np.ones((5,5),np.uint8)
k1 = (kernel == 1).astype('uint8')
mask = cv2.erode(mask, k1, borderType=cv2.BORDER_CONSTANT)
mask_inv = cv2.bitwise_not(mask)
difference = cv2.bitwise_or(resizedB, resizedB, mask=mask_inv)
result2 = cv2.bitwise_and(result, result, mask=mask)
result = cv2.add(result2, difference)
有关详细信息,请参阅SKAction reference。
答案 1 :(得分:1)
如果你想使用AVAudioPlayer
(而不是SpriteKit's
声音动作),你应该让声音在后台线程中播放,这样它的操作就不会干扰主线程你所有的视觉内容都是:
let soundQueue = OperationQueue()
soundQueue.qualityOfService = QualityOfService.background
soundQueue.addOperation{self.buttonClickSound.play()}