Pygame- “Pygbuttons”- 如何同时更改按钮颜色和播放声音
我想让每个按钮的颜色一个接一个地改变,每次颜色变化时都想播放一个声音。
声音播放得很好,但按钮的颜色只在所有声音播放完后才会改变。
我该怎么做才能让每个按钮的颜色变化和声音播放同时进行呢?
这是我的代码:
import pygame, pygbutton, sys
from pygame.locals import *
import time
import threading
from threading import Thread
FPS = 30
WINDOWWIDTH = 1550
WINDOWHEIGHT = 1200
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
BLACK = (0, 0, 0)
GREY = (211, 211, 211)
exitcode = 0
def main():
#1 constants
windowBgColor = WHITE
size=(100,30)
running = 1
#2 initialize
FPSCLOCK = pygame.time.Clock()
pygame.mixer.init(frequency=22050,size=-16,channels=13)
#3 load
zebrasound = pygame.mixer.Sound("resources/audio/zebra.wav")
zlet = pygame.mixer.Sound("resources/audio/Z.wav")
elet = pygame.mixer.Sound("resources/audio/E.wav")
blet = pygame.mixer.Sound("resources/audio/B.wav")
rlet = pygame.mixer.Sound("resources/audio/R.wav")
alet = pygame.mixer.Sound("resources/audio/A.wav")
wrong = pygame.mixer.Sound("resources/audio/fail.wav")
right = pygame.mixer.Sound("resources/audio/chime.wav")
beep = pygame.mixer.Sound("resources/audio/sensor.wav")
flip = pygame.mixer.Sound("resources/audio/flip.wav")
zebrasound.set_volume(3)
zlet.set_volume(3)
elet.set_volume(3)
blet.set_volume(3)
rlet.set_volume(3)
alet.set_volume(3)
wrong.set_volume(3)
right.set_volume(5)
#4 Display
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Animal game')
#5 Buttons
buttonForward = pygbutton.PygButton((700, 900, 600,482), normal='resources/images/arrow.png')
buttonBackward = pygbutton.PygButton((600, 900, 600,482), normal='resources/images/arrowBackward.png')
buttonZebra = pygbutton.PygButton((100, 150, 640,480), normal='resources/images/zebraclip.png')
buttonZebra1 = pygbutton.PygButton((850, 200, 600, 120), 'Z E B R A')
buttonZebra2 = pygbutton.PygButton((850, 400, 600, 120), 'Z A B R A')
buttonZebra3 = pygbutton.PygButton((850, 600, 600, 120), 'Z B R E A')
buttonZebra11 = pygbutton.PygButton((855, 205, 110, 110), 'Z')
buttonZebra12 = pygbutton.PygButton((975, 205, 110, 110), 'E')
buttonZebra13 = pygbutton.PygButton((1095, 205, 110, 110), 'B')
buttonZebra14 = pygbutton.PygButton((1215, 205, 110, 110), 'R')
buttonZebra15 = pygbutton.PygButton((1335, 205, 110, 110), 'A')
buttonZebra1.font = pygame.font.Font(None,110)
buttonZebra11.font = pygame.font.Font(None,110)
buttonZebra12.font = pygame.font.Font(None,110)
buttonZebra13.font = pygame.font.Font(None,110)
buttonZebra14.font = pygame.font.Font(None,110)
buttonZebra15.font = pygame.font.Font(None,110)
buttonZebra2.font = pygame.font.Font(None,110)
buttonZebra3.font = pygame.font.Font(None,110)
button = [buttonZebra,buttonZebra1,buttonZebra2,buttonZebra3]
button_zebra = [buttonZebra11,buttonZebra12,buttonZebra13,buttonZebra14,buttonZebra15]
allButtons = button
windowBgColor = WHITE
#6 Event loop
#while True:
while running:
#pygame.display.flip()
for event in pygame.event.get(): # event handling loop
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
if 'click' in button[0].handleEvent(event):
zebrasound.play()
if 'click' in button[1].handleEvent(event):
sound_please(right)
change_color_bg(button[1], GREEN)
change_color_fg(button_zebra[0], GREEN)
change_color_bg(button_zebra[0], BLACK)
sound_please(zlet)
change_color_fg(button_zebra[1], GREEN)
change_color_bg(button_zebra[1], BLACK)
sound_please(elet)
change_color_fg(button_zebra[2], GREEN)
change_color_bg(button_zebra[2], BLACK)
sound_please(blet)
change_color_fg(button_zebra[3], GREEN)
change_color_bg(button_zebra[3], BLACK)
sound_please(rlet)
change_color_fg(button_zebra[4], GREEN)
change_color_bg(button_zebra[4], BLACK)
sound_please(alet)
if 'click' in button[2].handleEvent(event):
sound_please(wrong)
change_color_bg(button[2], RED)
if 'click' in button[3].handleEvent(event):
sound_please(wrong)
change_color_bg(button[3], RED)
pygame.display.update()
screen.fill(windowBgColor)
buttonForward.draw(screen)
for a in allButtons:
a.draw(screen)
for b in button_zebra:
b.draw(screen)
pygame.display.update()
FPSCLOCK.tick(FPS)
def change_color_fg(button,color):
button.fgcolor = color
pygame.display.update()
def change_color_bg(button,color):
button.bgcolor = color
pygame.display.update()
def sound_please(sound):
sound.play()
while pygame.mixer.get_busy():
time.sleep(1)
pygame.display.update()
if __name__ == "__main__":
main()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit(0)
Button[1]
是大按钮,而 button_zebra 1,2,3,4
是大按钮里面的小按钮。
我在大按钮里有4个小按钮,当我点击大按钮时,它的颜色会改变。
1 个回答
-1
你发的代码主要是处理输入的部分,通常这只是游戏循环中的一部分。而你没有提供change_color_fg
的具体内容,所以我只能猜测一下。
我猜change_color_fg
并没有真正更新显示的内容,它只是改变了按钮应该用来绘制的颜色。之所以这么猜,是因为在一个函数里重复绘制显示内容是没有意义的,尤其是在同一帧内执行多次的时候。
首先,在更新循环中不要进行延迟。如果你需要在某个声音结束时做点什么,可以使用回调函数,或者每帧检查正在播放的声音,直到它们结束。
举个例子,当你播放每个声音时,可以用pygame.mixer.Sound.get_length
来检查声音的长度,然后安排一个函数在这段时间后执行,这个函数可以改变下一个按钮的颜色并播放下一个声音。或者,你可以从 pygame.mixer.Sound.play
中获取pygame.mixer.Channel
对象,然后使用pygame.mixer.Channel.get_busy
来检查,直到它返回False
,这表示声音已经停止播放,这时你就可以播放下一个声音了。