Pygame播放列表在后台连续播放 [英] Pygame Playlist Continuous in the Background
问题描述
我正在尝试为我的游戏获取背景音乐,但是我似乎无法完美地解决它.我过去曾经使用pygame,但在我的游戏积分中只使用了一首歌. 我希望播放列表连续播放,并随机选择每个曲目.我设法使它在单独的测试文件中工作.我将在下面将此代码发布下来.
I'm trying to get background music for my game, but I can't seem to figure it out perfectly. I've used pygame in the past, but it was only for one song during the credits of my game. I want the playlist to play continuously picking each track randomly. I've managed to get this working in a separate test file. I will post this code down below.
问题是当我在主游戏中调用此功能时,音乐会播放第一首曲目,然后停止播放.如果我输入
The problem is when I call this function in my main game, the music plays the first track, and then stops. If I put in
while pygame.mixer.music.get_busy():
continue
它只是播放音乐,而不能让我玩游戏.我希望它在用户玩游戏时不断在播放列表中循环播放(这是一个基于文本的游戏,因此它经常使用raw_input()
.
It just plays the music and doesn't let me play the game. I want it to loop continuously through the playlist while the user plays the game (it's a text based game so it uses raw_input()
a lot.
这是我的代码:
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
(P.S.我是通过Zed Shaw的"Learn Python The Hard Way"学习python的,所以我的游戏结构使用了本书中的Engine and Map系统)
(P.S. I learned python through Zed Shaw's "Learn Python The Hard Way" so my game structure uses the Engine and Map system from the book)
推荐答案
You can set a pygame.mixer.music.set_endevent() which get posted in the event queue when the music finishes. Then you just choose another song. Something along these lines:
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个部分
So the actual solution is just 3 parts
- 创建事件
MUSIC_ENDED = pygame.USEREVENT
. - 告诉pygame当歌曲结束后发布事件
pygame.mixer.music.set_endevent(MUSIC_ENDED)
- 在事件队列中检查事件
for event in pygame.event.get(): if event.type == MUSIC_ENDED:
- Create an event
MUSIC_ENDED = pygame.USEREVENT
. - Tell pygame to post the event when a song finishes
pygame.mixer.music.set_endevent(MUSIC_ENDED)
- Check for the event in the event queue
for event in pygame.event.get(): if event.type == MUSIC_ENDED:
然后您就可以随心所欲地做任何事情了.
And then you're free to do whatever you desire.
这篇关于Pygame播放列表在后台连续播放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!