Pygame播放列表在后台连续



我正在尝试为我的游戏获得背景音乐,但我似乎无法完美地弄清楚它。我过去曾经使用过Pygame,但是在我的游戏中仅仅是一首歌。我希望播放列表不断播放随机选择每个曲目。我设法在单独的测试文件中使此工作。我将在下面发布此代码。

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

while pygame.mixer.music.get_busy():
    continue

它只是播放音乐,不允许我玩游戏。我希望它在用户玩游戏时连续循环通过播放列表(这是基于文本的游戏,因此它经常使用raw_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

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

import threading
musicThread = threading.Thread(target=music)
musicThread.start()

如果您想停止音乐而不关闭游戏,则应杀死线程。

您可以设置pygame.mixer.music.set_endevent(),在音乐完成后将在事件队列中发布。然后,您只选择另一首歌。这些行:

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()

因此,实际解决方案仅为3部分

  1. 创建一个事件MUSIC_ENDED = pygame.USEREVENT
  2. 告诉PyGame歌曲完成pygame.mixer.music.set_endevent(MUSIC_ENDED)
  3. 时发布活动
  4. 在事件队列中检查事件 for event in pygame.event.get(): if event.type == MUSIC_ENDED:

然后您可以随意做任何您想做的事。

最新更新