0

How would I make it so that I can start a new line of text with pygame? For example if I have a variable and it has lots of text that doesn't all fit on the screen, how can I make it so that it appears on multiple lines. I tried using \n in between the text but it doesn't work. Here's an example of code:

import pygame

pygame.init()

display_width = 800
display_height = 600

black = (0,0,0)
white = (255,255,255)

gameDisplay = pygame.display.set_mode((display_width, display_height))
clock = pygame.time.Clock()

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

gameDisplay.fill(white)

text = "this is a lot of text and it won't all fit on the screen it needs to be on multiple lines but it doesn't right now and i need more text"

theText = pygame.font.Font("freesansbold.ttf", 20)
TextSurf, TextRect = text_objects(text, theText)
TextRect.center = (display_width/2, 10)
gameDisplay.blit(TextSurf, TextRect)

pygame.display.update()

Output: enter image description here

MatthewC
  • 63
  • 1
  • 6
  • See this answer for true multiline support in `pygame-ce` since version `2.1.4`: https://stackoverflow.com/questions/42014195/rendering-text-with-multiple-lines-in-pygame/75652828#75652828 – Matiiss Mar 07 '23 at 21:35

1 Answers1

2

There is no easy way out, you have to render each word separately and calculate if the width of the text extends the width of the surface (or screen). Here's an example:

import pygame
pygame.init()


SIZE = WIDTH, HEIGHT = (1024, 720)
FPS = 30
screen = pygame.display.set_mode(SIZE, pygame.RESIZABLE)
clock = pygame.time.Clock()


def blit_text(surface, text, pos, font, color=pygame.Color('black')):
    words = [word.split(' ') for word in text.splitlines()]  # 2D array where each row is a list of words.
    space = font.size(' ')[0]  # The width of a space.
    max_width, max_height = surface.get_size()
    x, y = pos
    for line in words:
        for word in line:
            word_surface = font.render(word, 0, color)
            word_width, word_height = word_surface.get_size()
            if x + word_width >= max_width:
                x = pos[0]  # Reset the x.
                y += word_height  # Start on new row.
            surface.blit(word_surface, (x, y))
            x += word_width + space
        x = pos[0]  # Reset the x.
        y += word_height  # Start on new row.


text = "This is a really long sentence with a couple of breaks.\nSometimes it will break even if there isn't a break " \
       "in the sentence, but that's because the text is too long to fit the screen.\nIt can look strange sometimes.\n" \
       "This function doesn't check if the text is too high to fit on the height of the surface though, so sometimes " \
       "text will disappear underneath the surface"
font = pygame.font.SysFont('Arial', 64)

while True:

    dt = clock.tick(FPS) / 1000

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

    screen.fill(pygame.Color('white'))
    blit_text(screen, text, (20, 20), font)
    pygame.display.update()

Result: result