简体   繁体   English

Pygame - 我可以让音乐有一个介绍然后一个循环点吗?

[英]Pygame - can I make music have an introduction and then a loop point?

I'm currently working on a game in Pygame, and I've been trying to think of a way to have a music track that loops at a point that isn't the beginning of the track.我目前正在 Pygame 开发一款游戏,我一直在想办法让音乐曲目在不是曲目的开头的地方循环播放。 So essentially, it plays an introduction, then moves onto another section that repeats without revisiting that introduction.所以本质上,它播放一个介绍,然后移动到另一个重复的部分而不重新访问该介绍。

I've thought of a couple of ways that almost worked, but they have problems.我想到了几种几乎可行的方法,但它们存在问题。

The first was to have two separate audio files for the introduction and the looping section, then to use pygame.music.set_endevent() , and just load the second audio file once the first is finished.第一个是为介绍和循环部分提供两个单独的音频文件,然后使用pygame.music.set_endevent() ,并在第一个音频文件完成后加载第二个音频文件。 This left quite an obvious gap and click though.这留下了相当明显的差距并点击了。

The second was to also use two audio files but to queue in the second as the first is loaded.第二个是也使用两个音频文件,但在加载第一个文件时排在第二个文件中。 The problem with this is that it seems like you can't change the play mode from 0 (play once) to -1 (looping) for the new queued track...问题在于,对于新排队的曲目,您似乎无法将播放模式从 0(播放一次)更改为 -1(循环)...

I feel like there has to be a way of doing this, I'd really appreciate any help.我觉得必须有一种方法可以做到这一点,我真的很感激任何帮助。

In the example below, PyGame's sound channels are used for multiple tracks.在下面的示例中,PyGame 的声道用于多个音轨。 Here an event is created, such that after 1500 milliseconds, a second sound in played (at the same time as the looping track).这里创建了一个事件,以便在 1500 毫秒后播放第二个声音(与循环曲目同时播放)。

For your suggested use-case, the code could play the intro-music at start, but also set an event-timer for /intro-length/ milliseconds in the future.对于您建议的用例,代码可以在开始时播放介绍音乐,但也可以在将来为/intro-length/毫秒设置一个事件计时器。 When that timer-event is received, the looping-part of your music could play continuously, as the intro should have just stopped.当收到该计时器事件时,您的音乐的循环部分可以连续播放,因为介绍应该刚刚停止。 Using multiple channels, it should not matter if the two sounds overlap by a few milliseconds (of silence/fadeout), as long as the user does not perceive it of course, Maybe it will be tricky to get the timing 100% correct on vastly different systems.使用多个通道,如果两个声音重叠几毫秒(无声/淡出)应该无关紧要,只要用户当然没有察觉到它,也许在大量的时间上 100% 正确地获得时间会很棘手不同的系统。 but it should get you close.但它应该让你接近。

Note that in the example, the sounds are already initialised into PyGame Sound objects, I expect this would cut-down on startup latency.请注意,在示例中,声音已经初始化为 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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM