首页 > 解决方案 > 我可以在 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 方法播放声音并同时做其他事情,但实际发生的是一切都冻结,播放声音,然后一切恢复。

标签: pythonpygame

解决方案


声音将在不同的线程中播放,并且不会停止执行。但是,您的循环包含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)

推荐阅读