python - 我可以在 Pygame 中播放声音并同时做其他事情吗?
问题描述
我正在用 python 和 pygame 制作一个小幻想控制台,但我偶然发现了一个问题。我正在制作一个可以制作 Chiptune 曲调的音乐编辑器,但是当我使用 pygame.mixer.Sound 方法播放它们时,它会暂停所有内容并播放声音。例如,如果我每次英雄捡起东西时播放声音,一切都会冻结,它会播放声音,然后一切都会恢复。起初这没什么大不了的,但它使做背景音乐之类的事情变得不可能。有可能解决这个问题吗?
我曾尝试使用 playsound 库,但这也会冻结所有内容。
def music(notes):
note_list = ["c","c2","d","d2","e","e2","f","f2","g","g2","a","a2"]
for i in note_list:
exec("{} = pygame.mixer.Sound('res/sounds/{}.wav')".format(i,i))
for i in notes:
for j in i:
exec("pygame.mixer.Sound.play({})".format(j))
time.sleep(.2)
我希望程序能够使用 pygame.mixer.Sound 方法播放声音并同时做其他事情,但实际发生的是一切都冻结,播放声音,然后一切恢复。
解决方案
声音将在不同的线程中播放,并且不会停止执行。但是,您的循环包含time.sleep(.2)
,这将停止执行0.2
几秒钟。你对每个音符都这样做,这意味着如果你有一首有 10 个音符的曲子,它会让你的程序暂停 2 秒。
对于您的特定问题,有许多不同的解决方案,这一切都取决于您如何构建调用此函数的代码。一种解决方案可能是安排事件,然后在它们出现在事件队列中时播放它们。另一种方法是在应该播放单个声音时调用它们。两者都需要一个游戏循环,因为您正在创建控制台游戏,所以我怀疑您是否拥有。
我会走简单的路线,将声音与您实际想要播放的联合声音结合起来,而不是连续播放许多不同的声音。您可以使用某些程序(例如Audacity)来编辑声音文件。然后,你甚至不需要一个函数。你可以打电话pygame.mixer.Sound.play(zelda_pickup_tune)
,一切都不会停止(假设zelda_pickup_tune
是一个包含有效Sound
对象的变量)。
另外,不要使用exec
. 如果您曾经让其他人使用您的代码,它会很慢并且可能会带来安全风险(不是您目前的确切用途,但如果您稍后进行一些小的更改,它很容易发生)。这也有点“神奇”,用其他语言重写这段代码是不可能的。
我建议对此类问题采用更标准的方法并使用字典。
def music(notes):
note_list = ["c","c2","d","d2","e","e2","f","f2","g","g2","a","a2"]
sounds = {} # Empty dictionary
for i in note_list:
sounds[i] = pygame.mixer.Sound('res/sounds/{}.wav'.format(i)) # Add note i as key and the sound as value.
for i in notes:
for j in i:
sounds[j].play() # Look up the sound with key i and play the sound.
time.sleep(.2)
推荐阅读
- c++ - 添加所需库后使用 TShark C++ 源文件剖析消息时未定义的引用
- java - Sentry Android - 构建发布 apk 时出现问题
- django - Spring MVC 和 Django
- c# - 当我在 C# 中使用“While”时,我不想打印最后一个计算
- java - 使用springboot连接oracle
- hyperledger-fabric - 织物样本中的高吞吐量链代码为 10 tps,我可以将其扩展到 100 tps 吗?我看到织物可以扩展到 100,000 tps
- javascript - 从渲染道具组件获取状态
- struts2 - 没有为命名空间 [/] 和操作名称 [hello] 映射的操作与上下文路径 [/HelloWorldStrut2] 关联
- mongodb - 有没有办法使用聚合来获取多个条件下的数据
- android - 是否有可能以编程方式在 android 中获得 SAR 值?如果可能比怎么做?