繁体   English   中英

如何在Pygame中将段落渲染到表面上

[英]How to render a paragraph onto a surface in pygame

我已经制作了一个功能齐全的主菜单,其中的按钮带您进入游戏,一个按钮带您进入说明页面。

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

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

这是我当前游戏GUI的屏幕截图: 游戏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)

pygame.font.Font对象的render()方法只能对单行文本进行对齐,如文档所述

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

  1. 创建一个将在其上绘制整个段落的新曲面。 要伪造透明表面,请使用Pygame的set_colorkey()方法。 1)
  2. 使用Python的内置splitlines()方法将文本分成几行字符。
  3. 如果要在段落表面内垂直对齐(例如居中)文本,请计算一个可选的偏移值。
  4. 在分割线上循环(即枚举):
    • 将当前字符行渲染到虚拟表面上。 1)
    • 计算该行的位置以适合段落样式。
    • 将虚拟曲面蒙到主段落曲面上。
  5. 将段落表面绘制到主屏幕上,或将其与其他参数一起返回。

现在是时候实现这一点了:

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

如果要使文本中的每一行居中,请不要将currentPostionx坐标设置为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 ,由于设置了段落表面的颜色键,可能会产生不良影响!

我希望这可以帮助你 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM