Могу ли я воспроизводить звук в Pygame и одновременно делать другие вещи? - PullRequest
0 голосов
/ 27 апреля 2019

Я делаю небольшую фантастическую консоль на python и pygame и наткнулся на проблему. Я создавал музыкальный редактор, который мог бы создавать мелодии микросхем, но когда я проигрывал их с помощью метода 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 и одновременно выполнять другие действия, но на самом деле происходит следующее: все зависает, воспроизводится звук, а затем все возобновляется.

1 Ответ

1 голос
/ 27 апреля 2019

Звук будет воспроизводиться в другом потоке и не остановит исполнение. Однако ваш цикл содержит 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...