Pygame如何为不同场景更换背景音乐?
How to change background music for different scenes in Pygame?
我想获取菜单和其他场景来播放不同的音乐,但我什么也做不了。这是代码:
正在设置 pygame:
pygame.init()
screen = pygame.display.set_mode((900,600),0,32)
clock = pygame.time.Clock()
font = pygame.font.Font('freesansbold.ttf', 32)
正在设置音乐:
pygame.mixer.init()
menuMusic = pygame.mixer.Sound("cs.mp3")
scene1Music = pygame.mixer.Sound("ut.mp3")
menu_channel = pygame.mixer.Channel(0)
scene1_channel = pygame.mixer.Channel(1)
class切换场景:
class GameState():
def __init__(self):
self.scene = self.menu
def menu(self, event_list):
menu_channel.play(menuMusic, loops=-1, fade_ms=5000)
screen.blit(font.render("Menu", True, 'white'), (60, 150))
for event in event_list:
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_presses = pygame.mouse.get_pressed()
if mouse_presses[0]:
self.state = self.scene1
def scene1(self, event_list):
scene1_channel.play(scene1Music, loops=-1, fade_ms=5000)
screen.blit(font.render("This is Scene1", True, 'white'), (WIDTH/15, 150))
主游戏循环:
game = GameState()
while True:
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
game.scene(event_list)
clock.tick(24)
现在只有当我将它们都移到开头时它才有效,尽管这不是我想要的,因为它们会同时一起玩。但是,如果我将 menu_channel.play(menuMusic, loops=-1, fade_ms=5000)
移动到菜单方法中,则不会播放任何内容。 scene1_channel.play(scene1Music, loops=-1, fade_ms=5000)
.
也是如此
问题是您每帧都在重新启动声音,而您应该只重新启动一次。快速而肮脏的解决方案是让你切换一个布尔值 music_started
,但更好的解决方案是重新考虑你的游戏状态 class.
一个class是为了封装一个东西,但是你把所有的场景都放在一个对象里了。相反,通常定义 Scene
class 并为每个场景创建子 classes。这个 class 通常应该有像 on_start
、on_update
和 on_exit
这样的方法(可能还有更多)。然后你可以确保你的场景做正确的事情。
import pygame
WIDTH, HEIGHT = 640, 480
class Scene:
def on_start(self):
pass
def update(self, events, dt):
pass
def on_exit(self):
pass
class Menu(Scene):
def __init__(self, screen, scenes):
self.scenes = scenes
self.screen = screen
self.font = pygame.font.SysFont('freesansbold.ttf', 32)
self.music = pygame.mixer.Sound("cs.mp3")
self.channel = pygame.mixer.Channel(0)
def on_start(self):
self.channel.play(self.music, loops=-1, fade_ms=5000)
def update(self, events, dt):
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
left_click, *_ = pygame.mouse.get_pressed()
if left_click:
return self.scenes['game']
self.screen.blit(self.font.render("Menu", True, 'white'), (60, 150))
return self
def on_exit(self):
self.channel.stop()
class Game(Scene):
def __init__(self, screen, scenes):
self.scenes = scenes
self.screen = screen
self.font = pygame.font.SysFont('freesansbold.ttf', 32)
self.music = pygame.mixer.Sound("cs.mp3")
self.channel = pygame.mixer.Channel(0)
self.timer = 0
def on_start(self):
self.channel.play(self.music, loops=-1, fade_ms=5000)
def update(self, events, dt):
# Go back to menu if there hasn't been any events for 5 seconds.
if not events:
self.timer += dt
if self.timer >= 5:
return self.scenes['menu']
else:
self.timer = 0
self.screen.blit(self.font.render("This is Scene1", True, 'white'), (WIDTH / 15, 150))
return self
def on_exit(self):
self.channel.stop()
def main():
pygame.init()
screen = pygame.display.set_mode((900, 600), 0, 32)
clock = pygame.time.Clock()
# All the scenes.
scenes = {}
scenes['menu'] = Menu(screen, scenes)
scenes['game'] = Game(screen, scenes)
# Start with the menu.
scene = scenes['menu']
scene.on_start()
while True:
dt = clock.tick(30) / 1000.0
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
return
# Switch scenes if there is a new scene.
new_scene = scene.update(events, dt)
if new_scene is not scene:
# If there is a new scene, make sure to allow the old
# scene to exit and the new scene to start.
scene.on_exit()
scene = new_scene
scene.on_start()
pygame.display.update()
if __name__ == '__main__':
main()
我想获取菜单和其他场景来播放不同的音乐,但我什么也做不了。这是代码:
正在设置 pygame:
pygame.init()
screen = pygame.display.set_mode((900,600),0,32)
clock = pygame.time.Clock()
font = pygame.font.Font('freesansbold.ttf', 32)
正在设置音乐:
pygame.mixer.init()
menuMusic = pygame.mixer.Sound("cs.mp3")
scene1Music = pygame.mixer.Sound("ut.mp3")
menu_channel = pygame.mixer.Channel(0)
scene1_channel = pygame.mixer.Channel(1)
class切换场景:
class GameState():
def __init__(self):
self.scene = self.menu
def menu(self, event_list):
menu_channel.play(menuMusic, loops=-1, fade_ms=5000)
screen.blit(font.render("Menu", True, 'white'), (60, 150))
for event in event_list:
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_presses = pygame.mouse.get_pressed()
if mouse_presses[0]:
self.state = self.scene1
def scene1(self, event_list):
scene1_channel.play(scene1Music, loops=-1, fade_ms=5000)
screen.blit(font.render("This is Scene1", True, 'white'), (WIDTH/15, 150))
主游戏循环:
game = GameState()
while True:
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
game.scene(event_list)
clock.tick(24)
现在只有当我将它们都移到开头时它才有效,尽管这不是我想要的,因为它们会同时一起玩。但是,如果我将 menu_channel.play(menuMusic, loops=-1, fade_ms=5000)
移动到菜单方法中,则不会播放任何内容。 scene1_channel.play(scene1Music, loops=-1, fade_ms=5000)
.
问题是您每帧都在重新启动声音,而您应该只重新启动一次。快速而肮脏的解决方案是让你切换一个布尔值 music_started
,但更好的解决方案是重新考虑你的游戏状态 class.
一个class是为了封装一个东西,但是你把所有的场景都放在一个对象里了。相反,通常定义 Scene
class 并为每个场景创建子 classes。这个 class 通常应该有像 on_start
、on_update
和 on_exit
这样的方法(可能还有更多)。然后你可以确保你的场景做正确的事情。
import pygame
WIDTH, HEIGHT = 640, 480
class Scene:
def on_start(self):
pass
def update(self, events, dt):
pass
def on_exit(self):
pass
class Menu(Scene):
def __init__(self, screen, scenes):
self.scenes = scenes
self.screen = screen
self.font = pygame.font.SysFont('freesansbold.ttf', 32)
self.music = pygame.mixer.Sound("cs.mp3")
self.channel = pygame.mixer.Channel(0)
def on_start(self):
self.channel.play(self.music, loops=-1, fade_ms=5000)
def update(self, events, dt):
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
left_click, *_ = pygame.mouse.get_pressed()
if left_click:
return self.scenes['game']
self.screen.blit(self.font.render("Menu", True, 'white'), (60, 150))
return self
def on_exit(self):
self.channel.stop()
class Game(Scene):
def __init__(self, screen, scenes):
self.scenes = scenes
self.screen = screen
self.font = pygame.font.SysFont('freesansbold.ttf', 32)
self.music = pygame.mixer.Sound("cs.mp3")
self.channel = pygame.mixer.Channel(0)
self.timer = 0
def on_start(self):
self.channel.play(self.music, loops=-1, fade_ms=5000)
def update(self, events, dt):
# Go back to menu if there hasn't been any events for 5 seconds.
if not events:
self.timer += dt
if self.timer >= 5:
return self.scenes['menu']
else:
self.timer = 0
self.screen.blit(self.font.render("This is Scene1", True, 'white'), (WIDTH / 15, 150))
return self
def on_exit(self):
self.channel.stop()
def main():
pygame.init()
screen = pygame.display.set_mode((900, 600), 0, 32)
clock = pygame.time.Clock()
# All the scenes.
scenes = {}
scenes['menu'] = Menu(screen, scenes)
scenes['game'] = Game(screen, scenes)
# Start with the menu.
scene = scenes['menu']
scene.on_start()
while True:
dt = clock.tick(30) / 1000.0
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
return
# Switch scenes if there is a new scene.
new_scene = scene.update(events, dt)
if new_scene is not scene:
# If there is a new scene, make sure to allow the old
# scene to exit and the new scene to start.
scene.on_exit()
scene = new_scene
scene.on_start()
pygame.display.update()
if __name__ == '__main__':
main()