Pygame - 我可以让音乐有一个介绍然后一个循环点吗?
Pygame - can I make music have an introduction and then a loop point?
我目前正在 Pygame 开发一款游戏,我一直在想办法让音乐曲目在不是曲目的开头的点循环播放.因此,从本质上讲,它会播放一个介绍,然后移动到另一个重复的部分,而不会重新访问该介绍。
我想过几个方法,几乎都行,但都存在问题。
第一个是为介绍和循环部分准备两个单独的音频文件,然后使用 pygame.music.set_endevent()
,并在第一个音频文件完成后加载第二个音频文件。这留下了相当明显的差距,但请点击。
第二个是也使用两个音频文件,但在加载第一个文件时排在第二个文件中。问题在于,您似乎无法将新排队曲目的播放模式从 0(播放一次)更改为 -1(循环)...
我觉得必须有办法做到这一点,我真的很感激任何帮助。
在下面的示例中,PyGame 的声道用于多个音轨。这里创建了一个事件,以便在 1500 毫秒后播放第二个声音(与循环曲目同时播放)。
对于您建议的用例,代码可以在开始时播放介绍音乐,但也可以在将来设置 /intro-length/ 毫秒的事件计时器.当收到该计时器事件时,您的音乐的循环部分可以连续播放,因为前奏应该刚刚停止。使用多个通道,如果两个声音重叠几毫秒(silence/fadeout)应该没有关系,当然只要用户没有察觉到它!在截然不同的系统上让时间 100% 正确可能会很棘手,但它应该能让你接近。
请注意,在示例中,声音已经初始化为 PyGame Sound
对象,我希望这会减少启动延迟。
import pygame
# Window size
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 400
DARK_BLUE = ( 3, 5, 54)
### initialisation
pygame.init()
pygame.mixer.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ) )
pygame.display.set_caption("Multi Sound with Timer")
### sound
# create separate Channel objects for simultaneous playback
channel1 = pygame.mixer.Channel(0) # argument must be int
channel2 = pygame.mixer.Channel(1)
# Rain sound from: https://www.freesoundslibrary.com/sound-of-rain-falling-mp3/ (CC BY 4.0)
rain_sound = pygame.mixer.Sound( 'rain-falling.ogg' )
channel1.play( rain_sound, -1 ) # loop the rain sound forever
# Car Horn sound from: https://www.freesoundslibrary.com/car-horn-sound-effect/ (CC BY 4.0)
horn_sound = pygame.mixer.Sound( 'car-horn.ogg' )
# Create a timer, which will (after the delay-time) post an event to the main loop
pygame.time.set_timer( pygame.USEREVENT, 1500 ) # play the horn in 1500 milliseconds
### Main Loop
clock = pygame.time.Clock()
done = False
while not done:
# Handle user-input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
elif ( event.type == pygame.USEREVENT ):
# Timer expired, play the sound
channel2.play( horn_sound )
# Movement keys
#keys = pygame.key.get_pressed()
#if ( keys[pygame.K_UP] ):
# print("up")
# Update the window, but not more than 60fps
window.fill( DARK_BLUE )
pygame.display.flip()
# Clamp FPS
clock.tick_busy_loop(60)
pygame.quit()
我目前正在 Pygame 开发一款游戏,我一直在想办法让音乐曲目在不是曲目的开头的点循环播放.因此,从本质上讲,它会播放一个介绍,然后移动到另一个重复的部分,而不会重新访问该介绍。
我想过几个方法,几乎都行,但都存在问题。
第一个是为介绍和循环部分准备两个单独的音频文件,然后使用 pygame.music.set_endevent()
,并在第一个音频文件完成后加载第二个音频文件。这留下了相当明显的差距,但请点击。
第二个是也使用两个音频文件,但在加载第一个文件时排在第二个文件中。问题在于,您似乎无法将新排队曲目的播放模式从 0(播放一次)更改为 -1(循环)...
我觉得必须有办法做到这一点,我真的很感激任何帮助。
在下面的示例中,PyGame 的声道用于多个音轨。这里创建了一个事件,以便在 1500 毫秒后播放第二个声音(与循环曲目同时播放)。
对于您建议的用例,代码可以在开始时播放介绍音乐,但也可以在将来设置 /intro-length/ 毫秒的事件计时器.当收到该计时器事件时,您的音乐的循环部分可以连续播放,因为前奏应该刚刚停止。使用多个通道,如果两个声音重叠几毫秒(silence/fadeout)应该没有关系,当然只要用户没有察觉到它!在截然不同的系统上让时间 100% 正确可能会很棘手,但它应该能让你接近。
请注意,在示例中,声音已经初始化为 PyGame Sound
对象,我希望这会减少启动延迟。
import pygame
# Window size
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 400
DARK_BLUE = ( 3, 5, 54)
### initialisation
pygame.init()
pygame.mixer.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ) )
pygame.display.set_caption("Multi Sound with Timer")
### sound
# create separate Channel objects for simultaneous playback
channel1 = pygame.mixer.Channel(0) # argument must be int
channel2 = pygame.mixer.Channel(1)
# Rain sound from: https://www.freesoundslibrary.com/sound-of-rain-falling-mp3/ (CC BY 4.0)
rain_sound = pygame.mixer.Sound( 'rain-falling.ogg' )
channel1.play( rain_sound, -1 ) # loop the rain sound forever
# Car Horn sound from: https://www.freesoundslibrary.com/car-horn-sound-effect/ (CC BY 4.0)
horn_sound = pygame.mixer.Sound( 'car-horn.ogg' )
# Create a timer, which will (after the delay-time) post an event to the main loop
pygame.time.set_timer( pygame.USEREVENT, 1500 ) # play the horn in 1500 milliseconds
### Main Loop
clock = pygame.time.Clock()
done = False
while not done:
# Handle user-input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
elif ( event.type == pygame.USEREVENT ):
# Timer expired, play the sound
channel2.play( horn_sound )
# Movement keys
#keys = pygame.key.get_pressed()
#if ( keys[pygame.K_UP] ):
# print("up")
# Update the window, but not more than 60fps
window.fill( DARK_BLUE )
pygame.display.flip()
# Clamp FPS
clock.tick_busy_loop(60)
pygame.quit()