如何在pygame中将段落渲染到曲面上

时间:2016-01-09 15:34:57

标签: python pygame

我制作了一个功能齐全的主菜单,其中包含一个按钮带您进入游戏,另一个按钮带您进入指示页面。

但是,在我的说明页面中,我只能写一个单行句子。如果我添加多行,它会在中间显示正方形。

我想要达到的目的是在屏幕上写一个多行段落来显示一些指令,游戏信息等。

这是我当前游戏GUI的屏幕截图: Game GUI

这是我到目前为止的相关代码:

def text_objects(text, font):
   textSurface = font.render(text, True, (0,0,0))
   return textSurface, textSurface.get_rect()


def ParagraphText(text, font):
   ParagraphSize = (600,500)
   FontSize = font.get_height()

   ParagraphSurf = pygame.Surface(ParagraphSize)

   ParagraphSurf.fill(WHITE)
   ParagraphSurf.set_colorkey(WHITE)

   SplitLines = text.splitlines()

   CentreText = (ParagraphSize[1] - len(SplitLines)*(FontSize + 1)//2)

   for idx, line in enumerate(SplitLines):
       currentTextline = font.render(text, False, (0, 0, 0))
       currentPostion = (0, idx * FontSize + CentreText)
       ParagraphSurf.blit(currentTextline, currentPostion)

   return ParagraphSurf, ParagraphSize



def Instructions():
   paragraph = """Your are the last surviving rhino. Your horn
   is worth millions! Right now you are trapped in a zoo and
   waiting to be slaughtered for your horn. But you can't give
   up! Escape from the tribesmen and zoo security so you can
   enjoy your life as a free being once again"""

   screen.blit(pygame.image.load("background0.jpg").convert(), (0,0))
   InstructionsFont = pygame.font.SysFont("elephant",15)
   TextSurf, TextRect = text_objects("Instructions", InstructionsFont)
   TextRect.center = ((screen_width/2),(screen_height/6))
   screen.blit(TextSurf, TextRect)

   ParagraphText(paragraph,InstructionsFont)

   intro = True

   while intro:
       for event in pygame.event.get():
           if event.type == pygame.QUIT:
               pygame.quit()
               quit()

       Buttons("BACK",100,500,120,50,TURQUOISE,DARK_TURQUOISE,"back")

       pygame.display.update()
       clock.tick(15)

1 个答案:

答案 0 :(得分:1)

render()对象的pygame.font.Font方法只能点击单行文字,如documentation中所述。

要解决此问题,您必须调整text_objects()函数,将传入的文本字符串的每一行分别绘制到适当的位置:

  1. 创建一个新的曲面,将在其上绘制整个段落。假冒透明表面使用Pygame的set_colorkey()方法。 1)
  2. 使用Python的内置splitlines()方法将文本拆分为多行字符。
  3. 如果要在段落曲面内垂直对齐(例如居中)文本,请计算可选的偏移值。
  4. 在分割线上循环(即枚举):
    • 将当前字符行渲染到虚拟表面上。 1)
    • 计算此行的位置以适合段落样式。
    • 将虚拟表面滑动到主段落表面上。
  5. 将段落表面绘制到主屏幕上或使用其他参数返回。
  6. 现在是时候实现这个了:

    def text_objects(text, font):
        paragraphSize = (xsize, ysize)
        fontSize = font.get_height()
    
        # Step 1
        paragraphSurface = pygame.Surface(paragraphSize ) 
    
        #Set colorkey to fake transparent paragraph surface
        paragraphSurface.fill((255, 255, 255))
        paragraphSurface.set_colorkey((255, 255, 255))
    
        # Step 2
        splitLines = text.splitlines() 
    
        # Step 3: center the text vertically 
        offSet = (paragraphSize[1] - len(splitLines) * (fontSize + 1)) // 2 
    
        #Step 4
        for idx, line in enumerate(splitLines):
            currentTextline = font.render(line, False, (0, 0, 0))
            currentPostion = (0, idx * fontSize + offSet)
            paragraphSurface.blit(currentTextline, currentPostion)
    
        #Step 5
        return paragraphSurface, paragraphSize
    

    如果您想要将文本中的每一行居中,请不要将x - currentPostion的坐标设置为0,但请使用以下计算:

    #center paragraph
    currentPostion = ((paragraphSize[0] - currentTextline.get_width()) // 2, #x-coordinate
                      idx * fontSize + offSet) #y-coordinate
    

    sample: center text

    或右对齐:

    #right align paragraph
    currentPostion = (paragraphSize[0] - currentTextline.get_width(), #x-coordinate
                      idx * fontSize + offSet) #y-coordinate
    

    sample: right align

    1) 请注意,在渲染一行时将antialias参数设置为true可能会产生不良影响,因为设置的颜色键是段落表面!

    我希望这可以帮助你:)