I'm trying to create this reference piano by using pygame. I created a Button class and tried to annotate them but only 1 button has annotation. How can I annotate all of the buttons?
Referance piano:
My pygame result:
My pygame script:
import pygame, sys
pygame.init()
BUTTONWIDTH = 75
BUTTONHEIGHT = 300
SHARPSCALE = 2
SHARPWIDTH = BUTTONWIDTH // SHARPSCALE
SHARPHEIGHT = BUTTONHEIGHT // SHARPSCALE
DISPLAYWIDTH = BUTTONWIDTH * 7
DISPLAYHEIGHT = BUTTONHEIGHT
DISPLAYSURF = pygame.display.set_mode((DISPLAYWIDTH,DISPLAYHEIGHT))
DISPLAYRECT = DISPLAYSURF.get_rect()
CLOCK = pygame.time.Clock()
FRAMERATE = 60
FONT = pygame.font.SysFont(None, 45)
class Button(pygame.sprite.Sprite):
def __init__(self,width,height,text,mode,**pos):
super().__init__()
if mode == 'normal' : self.colors = {'on_click':'#bcbcbc', 'on_button':'#eeeeee', 'on_normal':'#ffffff'}
elif mode == 'sharp' : self.colors = {'on_click':'#4f5b62', 'on_button':'#263238', 'on_normal':'#000a12'}
else : raise NameError('Unknown button mode')
self.image = pygame.Surface((width,height))
self.rect = self.image.get_rect(**pos)
self.color = self.colors['on_normal']
self.image.fill(self.color)
text_color = 'black' if mode=='normal' else 'white'
self.text_surf = FONT.render(text, True, text_color)
self.text_rect = self.text_surf.get_rect(midtop=self.rect.center)
self.image.blit(self.text_surf, self.text_rect)
def update(self):
pos = pygame.mouse.get_pos()
#keys = pygame.key.get_pressed()
if self.rect.collidepoint(pos):
left, _ ,_ = pygame.mouse.get_pressed()
if left : self.color = self.colors['on_click' ]
else : self.color = self.colors['on_button']
else : self.color = self.colors['on_normal']
self.image.fill(self.color)
self.image.blit(self.text_surf, self.text_rect)
Buttons = pygame.sprite.Group()
C = Button(BUTTONWIDTH, BUTTONHEIGHT, 'C' , mode='normal', topleft=DISPLAYRECT.topleft)
C_ = Button(SHARPWIDTH , SHARPHEIGHT , 'C#', mode='sharp' , midtop =C.rect.topright)
D = Button(BUTTONWIDTH, BUTTONHEIGHT, 'D' , mode='normal', topleft=C.rect.topright)
D_ = Button(SHARPWIDTH , SHARPHEIGHT , 'D#', mode='sharp' , midtop =D.rect.topright)
E = Button(BUTTONWIDTH, BUTTONHEIGHT, 'E' , mode='normal', topleft=D.rect.topright)
F = Button(BUTTONWIDTH, BUTTONHEIGHT, 'F' , mode='normal', topleft=E.rect.topright)
F_ = Button(SHARPWIDTH , SHARPHEIGHT , 'F#', mode='sharp' , midtop =F.rect.topright)
G = Button(BUTTONWIDTH, BUTTONHEIGHT, 'G' , mode='normal', topleft=F.rect.topright)
G_ = Button(SHARPWIDTH , SHARPHEIGHT , 'G#', mode='sharp' , midtop =G.rect.topright)
A = Button(BUTTONWIDTH, BUTTONHEIGHT, 'A' , mode='normal', topleft=G.rect.topright)
A_ = Button(SHARPWIDTH , SHARPHEIGHT , 'A#', mode='sharp' , midtop =A.rect.topright)
B = Button(BUTTONWIDTH, BUTTONHEIGHT, 'B' , mode='normal', topleft=A.rect.topright)
Buttons.add(C,D,E,F,G,A,B,C_,D_,F_,G_,A_)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
Buttons.draw(DISPLAYSURF)
Buttons.update()
pygame.display.update()
CLOCK.tick(FRAMERATE)
Optinal question: How can I avoid pressing both normal and sharp buttons?


