pygame 屏幕上未显示文本

texts are not shown on pygame screen

我正在尝试使用 pygame 创建这架参考钢琴。我创建了一个按钮 class 并尝试对其进行注释,但只有 1 个按钮具有注释。如何注释所有按钮?

参考钢琴:

我的 pygame 结果:

我的 pygame 脚本:

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)   

可选问题:如何避免同时按下普通按钮和快速按钮?

您没有在屏幕上绘制文本。您在按钮上绘制文本。因此文字的位置需要设置在按钮的坐标系Surface中。按钮在屏幕的左上角有一个绝对坐标。但是,Surface 的左上角始终是 (0, 0)。

self.text_rect = self.text_surf.get_rect(midtop=self.rect.center)

self.text_rect = self.text_surf.get_rect(midtop=self.image.get_rect().center)

请注意,如果您在 200x200 的屏幕上有一个尺寸为 100x100 的 Surface,则 Surface 的中心是(250, 250).
如果你想在 Surface 的中心在屏幕上放置一些文本,你必须在 (250, 250).
处绘制它 但是,如果要在中心的 Surface 本身(尺寸为 100 x 100)上绘制文本,则需要将其绘制在 (50, 50).