代码之家  ›  专栏  ›  技术社区  ›  ScalaBoy

如何在矩形内添加文本?

  •  1
  • ScalaBoy  · 技术社区  · 6 年前

    我定义了对象的类 fences 具体如下:

    class GeoFence(pygame.sprite.Sprite):
        def __init__(self, rect, risk_level, *groups):
            self._layer = 1
            pygame.sprite.Sprite.__init__(self, groups)
            self.image = pygame.surface.Surface((rect.width, rect.height))
            self.image.fill(GREEN)
            self.rect = rect
            self.risk_level = risk_level
            self.font = pygame.font.SysFont('Arial', 25)
            screen.blit(self.font.render(risk_level, True, (255,0,0)), (200, 100))
    

    每个对象 fence 是一个绿色矩形。我想在这个矩形内显示一个文本。文本由字符串定义 risk_level 从列表中随机选择的 risks .

    all_sprites = pygame.sprite.LayeredUpdates()
    fences = pygame.sprite.Group()
    
    risks = ["HIGH","MEDIUM","LOW"]
    for rect in (pygame.Rect(510,150,75,52), pygame.Rect(450,250,68,40), pygame.Rect(450,370,68,48)):
        risk = risks[random.randint(0,2)]
        GeoFence(rect, risk, all_sprites, fences)
    

    此代码不会失败,但标题不会显示在屏幕上的任何位置。

    1 回复  |  直到 6 年前
        1
  •  1
  •   skrx    6 年前

    问题是你在坐标系上快速输入文字 (200, 100) screen 创建精灵时的曲面,因此当在下一帧中清除屏幕时,文本将消失。

    为了在 GeoFence 对象,你需要把它放到 self.image 在坐标系 (0, 0) (如果应该左上对齐)。

    如果表面应适合文本的大小,则可以先渲染文本表面,并将其大小用作 自我形象 表面。

    import random
    import pygame
    
    
    pygame.init()
    screen = pygame.display.set_mode((640, 480))
    clock = pygame.time.Clock()
    BG_COLOR = pygame.Color('gray12')
    GREEN = pygame.Color('green')
    FONT = pygame.font.SysFont('Arial', 25)
    
    
    class GeoFence(pygame.sprite.Sprite):
    
        def __init__(self, rect, risk_level, *groups):
            self._layer = 1
            pygame.sprite.Sprite.__init__(self, groups)
            text_surface = FONT.render(risk_level, True, (255,0,0))
            self.image = pygame.surface.Surface(text_surface.get_size())
            self.image.fill(GREEN)
            self.image.blit(text_surface, (0, 0))
            self.rect = self.image.get_rect(topleft=rect.topleft)
            self.risk_level = risk_level
    
    
    all_sprites = pygame.sprite.LayeredUpdates()
    fences = pygame.sprite.Group()
    
    risks = ["HIGH","MEDIUM","LOW"]
    for rect in (pygame.Rect(510,150,75,52), pygame.Rect(450,250,68,40),
                 pygame.Rect(450,370,68,48)):
        risk = random.choice(risks)
        GeoFence(rect, risk, all_sprites, fences)
    
    done = False
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
    
        all_sprites.update()
    
        screen.fill(BG_COLOR)
        all_sprites.draw(screen)
        pygame.display.flip()
        clock.tick(60)
    

    也可以将另一种颜色传递给 Font.render 它将用作背景色。这将允许您稍微缩短代码:

    class GeoFence(pygame.sprite.Sprite):
    
        def __init__(self, rect, risk_level, *groups):
            self._layer = 1
            pygame.sprite.Sprite.__init__(self, groups)
            self.image = FONT.render(risk_level, True, (255,0,0), GREEN)
            self.rect = self.image.get_rect(topleft=rect.topleft)
            self.risk_level = risk_level
    

    如果要使文本居中,请为文本创建另一个矩形,并设置其 center self.rect.center 然后将其用作文本的blit位置。这个 self.rect 执行此操作时应仍处于默认位置(0,0)。

    def __init__(self, rect, risk_level, *groups):
        self._layer = 1
        pygame.sprite.Sprite.__init__(self, groups)
        text_surface = FONT.render(risk_level, True, (255,0,0))
        self.image = pygame.surface.Surface(
            (text_surface.get_width()+110, text_surface.get_height()+20))
        self.image.fill(GREEN)
        # Create the rect, but don't set the coordinates yet.
        self.rect = self.image.get_rect()
        # Set the center of the text_rect to the center of the self.rect.
        text_rect = text_surface.get_rect(center=self.rect.center)
        # Then blit the text at the text_rect and it will be centered.
        self.image.blit(text_surface, text_rect)
        # Afterwards set the rect to the desired position.
        self.rect.topleft = rect.topleft