Python Pygame播放列表在后台连续播放

Python Pygame播放列表在后台连续播放,python,background,pygame,Python,Background,Pygame,我正试着为我的游戏准备背景音乐,但我似乎不能很好地理解它。我以前用过pygame,但在我的游戏中只有一首歌。 我希望播放列表连续播放,随机选取每首曲目。我已经设法在一个单独的测试文件中实现了这一点。我将在下面发布此代码 问题是,当我在主游戏中调用此函数时,音乐播放第一首曲目,然后停止。如果我投入 while pygame.mixer.music.get_busy(): continue 它只是播放音乐,不让我玩游戏。我想让它在用户玩游戏时不断循环播放列表(这是一个基于文本的游戏,所以它

我正试着为我的游戏准备背景音乐,但我似乎不能很好地理解它。我以前用过pygame,但在我的游戏中只有一首歌。 我希望播放列表连续播放,随机选取每首曲目。我已经设法在一个单独的测试文件中实现了这一点。我将在下面发布此代码

问题是,当我在主游戏中调用此函数时,音乐播放第一首曲目,然后停止。如果我投入

while pygame.mixer.music.get_busy():
    continue
它只是播放音乐,不让我玩游戏。我想让它在用户玩游戏时不断循环播放列表(这是一个基于文本的游戏,所以它经常使用
raw\u input()

这是我的密码:

import pygame
import random

pygame.mixer.init()

_songs = [songs, are, here]

_currently_playing_song = None

def music():
    global _currently_playing_song, _songs
    next_song = random.choice(_songs)
    while next_song == _currently_playing_song:
        next_song = random.choice(_songs)
    _currently_playing_song = next_song
    pygame.mixer.music.load(next_song)
    pygame.mixer.music.play()

while True: ## This part works for the test, but will not meet my needs
    music() ## for the full game.
    while pygame.mixer.music.get_busy():
        continue

(另外,我是通过Zed Shaw的“艰苦学习python”学习python的,因此我的游戏结构使用了书中的引擎和地图系统)

你可以使用线程在后台播放音乐

import threading
musicThread = threading.Thread(target=music)
musicThread.start()
如果你想在不关闭游戏的情况下停止音乐,你应该终止线程。

你可以设置一个在音乐结束时发布到事件队列中的消息。然后你只需选择另一首歌曲。大致如下:

import os
import pygame
pygame.init()
pygame.mixer.init()

SIZE = WIDTH, HEIGHT = 720, 460
screen = pygame.display.set_mode(SIZE)

MUSIC_ENDED = pygame.USEREVENT
pygame.mixer.music.set_endevent(MUSIC_ENDED)


BACKGROUND = pygame.Color('black')


class Player:

    def __init__(self, position):
        self.position = pygame.math.Vector2(position)
        self.velocity = pygame.math.Vector2()

        self.image = pygame.Surface((32, 32))
        self.rect =  self.image.get_rect(topleft=self.position)

        self.image.fill(pygame.Color('red'))

    def update(self, dt):
        self.position += self.velocity * dt
        self.rect.topleft = self.position


def load_music(path):
    songs = []
    for filename in os.listdir(path):
        if filename.endswith('.wav'):
            songs.append(os.path.join(path, filename))
    return songs


def run():
    songs = load_music(path='/Users/Me/Music/AwesomeTracks')

    song_index = 0  # The current song to load
    pygame.mixer.music.load(songs[song_index])
    pygame.mixer.music.play()
    song_index += 1

    clock = pygame.time.Clock()
    player = Player(position=(WIDTH / 2, HEIGHT / 2))

    while True:
        dt = clock.tick(30) / 1000

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_a:
                    player.velocity.x = -200
                elif event.key == pygame.K_d:
                    player.velocity.x = 200
                elif event.key == pygame.K_w:
                    player.velocity.y = -200
                elif event.key == pygame.K_s:
                    player.velocity.y = 200
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_a or event.key == pygame.K_d:
                    player.velocity.x = 0
                elif event.key == pygame.K_w or event.key == pygame.K_s:
                    player.velocity.y = 0
            elif event.type == MUSIC_ENDED:
                song_index = (song_index + 1) % len(songs)  # Go to the next song (or first if at last).
                pygame.mixer.music.load(songs[song_index])
                pygame.mixer.music.play()

        screen.fill(BACKGROUND)

        player.update(dt)
        screen.blit(player.image, player.rect)

        pygame.display.update()

run()
所以实际的解决方案只有三个部分

  • 创建一个事件
    MUSIC\u ENDED=pygame.USEREVENT
  • 告诉pygame在歌曲结束后发布活动
    pygame.mixer.music.set\u endevent(music\u ENDED)
  • 检查事件队列中的事件 pygame.event.get()中事件的
    :如果event.type==MUSIC\u结束:

  • 然后你可以自由地做任何你想做的事。

    这是不必要的,因为pygame会自动为音乐创建一个线程。这会告诉你如果最后一首歌曲完成了,如何播放一首随机歌曲,或者按向右箭头键循环播放歌曲列表。@Macimoar这是正确的答案,你真的不需要
    线程。
    。我不知道为什么另一个有更多的投票。您可以通过单击复选标记将此问题标记为已解决来接受您最喜欢的答案。此解决方案对于播放列表的重复效果很好,但它不允许我在播放音乐时玩游戏(我只有一个闪烁的光标,音乐继续播放,直到我中断为止)。我不太清楚为什么。@Macimoar这个
    运行
    函数应该是您的主游戏循环的一部分。单独运行此代码只会重复播放音乐。问题的实际解决方案是,每当音乐停止时,您将事件放入游戏中的事件队列,以便您可以更改歌曲“我用了一个更完整的例子来说明我的观点。你所要做的就是在事件循环中检查
    音乐结束的事件,如果它在那里,你可以播放另一首歌。然后你可以随机播放一首歌,从播放列表中选择,转到下一首歌,或者在游戏结束后停止游戏。”。