Pygame-“Pygbuttons” - 如何同时更改按钮颜色和声音播放

时间:2014-06-17 14:43:21

标签: python pygame

我想逐个改变每个按钮的颜色,每次改变颜色我想播放一个声音。

声音播放完美,但只有在播放完所有声音时,按钮颜色才会改变。

我该怎么做才能同时为每个按钮进行换色和声音播放?

这是我的代码:

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是bigbutton中的小按钮。

我在一个bigbutton中有4个按钮,当我点击bigbutton时,它的颜色会发生变化。

1 个答案:

答案 0 :(得分:-1)

由于输入处理(您发布的代码部分)通常只是游戏循环的一部分,并且您尚未发布change_color_fg的内容,因此我只能在这里进行有根据的猜测。< / p>

我的猜测是change_color_fg实际上并没有更新显示,只是改变按钮假设要绘制的颜色。这是我的猜测,部分是因为在一个帧内多次执行的函数中重新绘制显示是没有意义的。

首先,不要在更新循环中间延迟。如果您需要在单个声音结束时执行某些操作,请执行回调,或者检查播放声音是否每帧完成一次,直到完成为止。

例如,对于您播放的每个声音,您可以使用pygame.mixer.Sound.get_length检查其长度,然后安排一段时间后执行的功能会改变下一个按钮的颜色并播放下一个声音。或者,您可以获取pygame.mixer.Channel对象back from pygame.mixer.Sound.play,然后检查pygame.mixer.Channel.get_busy,直到它返回False,这表示您的声音已停止播放,此时您可以玩下一个。