Python/Pygame 在 Pygame 中使文本在离开窗口时换行 [英] Python/Pygame make text in Pygame wrap when in leaves the window

查看:129
本文介绍了Python/Pygame 在 Pygame 中使文本在离开窗口时换行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个渲染文本的文本函数.函数如下

def textFunc(font,msg,color,x,y,center):text_render = font.render(msg,True,color)text_rect = text_render.get_rect()#如果center为真,则以X,Y为中心如果中心 == 真:text_rect.center = (x,y)别的:text_rect = (x,y)game_display.blit(text_render,text_rect)

但是我的 msg 字符串太长,它会在窗口外呈现.

有没有办法让我的文本注册对我的窗口来说太长并在文本开头下方继续?类似于计算机如何自动完成

有点像这样:

解决方案

没有自动解决方案.您必须自己实现文本换行并逐行逐字绘制文本.
幸运的是 PyGame wiki 为这个任务提供了一个函数.请参阅 PyGame wiki

导入pygamepygame.init()font = pygame.font.SysFont(None, 40)msg = "简单的函数,将绘制文本并包装它以适应传递的矩形.如果有任何文本无法放入框中,则将返回剩余文本."textRect = pygame.Rect(100, 100, 300, 300)窗口 = pygame.display.set_mode((500, 500))运行 = 真运行时:对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:运行 = 错误window.fill((255, 255, 255))pygame.draw.rect(window, (0, 0, 0), textRect, 1)drawTextRect = textRect.inflate(-5, -5)drawText(window, msg, (0, 0, 0), drawTextRect, font, textAlignBlock, True)pygame.display.flip()

I have a text function that render text.The function is the following

def textFunc(font,msg,color,x,y,center):
    text_render = font.render(msg,True,color)
    text_rect = text_render.get_rect()
    
    #If center is true, then the X,Y will be used as the center
    if center == True:
        text_rect.center = (x,y)
    else:
        text_rect = (x,y)
    game_display.blit(text_render,text_rect)

However is my msg string is too long it will render outside the window.

Is there a way for my text to register that is too long for my window and so continues below the start of the text? Similarly to how computers do it automaticall

Sort of like so:

解决方案

There is no automatic solution. You have to implement the text wrap by yourself and draw the text line by line respectively word by word.
Fortunately PyGame wiki provides a function that for this task. See PyGame wiki Simple Text Wrapping for pygame.

I've extended the function and added an additional argument, which provides left or right aligned text, centered text or even block mode:

textAlignLeft = 0
textAlignRight = 1
textAlignCenter = 2
textAlignBlock = 3

def drawText(surface, text, color, rect, font, align=textAlignLeft, aa=False, bkg=None):
    lineSpacing = -2
    spaceWidth, fontHeight = font.size(" ")[0], font.size("Tg")[1]

    listOfWords = text.split(" ")
    if bkg:
        imageList = [font.render(word, 1, color, bkg) for word in listOfWords]
        for image in imageList: image.set_colorkey(bkg)
    else:
        imageList = [font.render(word, aa, color) for word in listOfWords]

    maxLen = rect[2]
    lineLenList = [0]
    lineList = [[]]
    for image in imageList:
        width = image.get_width()
        lineLen = lineLenList[-1] + len(lineList[-1]) * spaceWidth + width
        if len(lineList[-1]) == 0 or lineLen <= maxLen:
            lineLenList[-1] += width
            lineList[-1].append(image)
        else:
            lineLenList.append(width)
            lineList.append([image])

    lineBottom = rect[1]
    lastLine = 0
    for lineLen, lineImages in zip(lineLenList, lineList):
        lineLeft = rect[0]
        if align == textAlignRight:
            lineLeft += + rect[2] - lineLen - spaceWidth * (len(lineImages)-1)
        elif align == textAlignCenter:
            lineLeft += (rect[2] - lineLen - spaceWidth * (len(lineImages)-1)) // 2
        elif align == textAlignBlock and len(lineImages) > 1:
            spaceWidth = (rect[2] - lineLen) // (len(lineImages)-1)
        if lineBottom + fontHeight > rect[1] + rect[3]:
            break
        lastLine += 1
        for i, image in enumerate(lineImages):
            x, y = lineLeft + i*spaceWidth, lineBottom
            surface.blit(image, (round(x), y))
            lineLeft += image.get_width() 
        lineBottom += fontHeight + lineSpacing

    if lastLine < len(lineList):
        drawWords = sum([len(lineList[i]) for i in range(lastLine)])
        remainingText = ""
        for text in listOfWords[drawWords:]: remainingText += text + " "
        return remainingText
    return ""


Minimal example:

import pygame

pygame.init()
font = pygame.font.SysFont(None, 40)

msg = "Simple function that will draw text and wrap it to fit the rect passed.  If there is any text that will not fit into the box, the remaining text will be returned."
textRect = pygame.Rect(100, 100, 300, 300)

window = pygame.display.set_mode((500, 500))
run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    window.fill((255, 255, 255))
    pygame.draw.rect(window, (0, 0, 0), textRect, 1)
    drawTextRect = textRect.inflate(-5, -5)
    drawText(window, msg, (0, 0, 0), drawTextRect, font, textAlignBlock, True)
    pygame.display.flip()

这篇关于Python/Pygame 在 Pygame 中使文本在离开窗口时换行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆