0
\$\begingroup\$

I'm trying to make a dialog box with pygame, and initially everything was going well. I printed the letters sequentially on the screen and it works very well in a single line of text, but when I use \n to add an extra line it does not go to the new line.

When I searched, I found that pygame.font.Font and pygame.font.SysFont could not print \n. So what do you think, how should I go about printing multi-line messages?

\$\endgroup\$
1
  • \$\begingroup\$ Split your text in multiple labels? \$\endgroup\$
    – Vaillancourt
    Jun 26, 2022 at 2:09

1 Answer 1

2
\$\begingroup\$

I saw this question two weeks ago, but I didn't really have the time to properly answer it so I left it for someone more experienced to answer. I'm a little surprised that this question has not yet been answered (nor flagged as I'm sure it's a duplicate).

So, the answer is that .Font.render() and .SysFont.render() do not process newlines, as is stated in the documentation. The solution is to keep track of the height of everything you have been printing so that you can begin displaying text on the next line. It's actually a lot easier than it sounds:

import pygame

SIZE = 80
OFFSET = 0

pygame.init()

WHITE = pygame.Color(255,255,255)
BLACK = (0,0,0)

display = pygame.display.set_mode((500, 500))
pygame.display.set_caption("Font Test")
display.fill(WHITE)
pygame.display.flip()

fobj = pygame.font.SysFont(pygame.font.get_default_font(), SIZE)

nextLine = 0

#display first line
t = "Line 1"
txt = fobj.render(t, 0, BLACK)
display.blit(txt, (0,0))
nextLine += fobj.size(t)[1] + OFFSET

#display second line
t = "Line 2"
txt = fobj.render(t, 0, BLACK)
display.blit(txt, (0,nextLine))
nextLine += fobj.size(t)[1] + OFFSET

#display third line
t = "Line 3"
txt = fobj.render(t, 0, BLACK)
display.blit(txt, (0,nextLine))
nextLine += fobj.size(t)[1] + OFFSET

pygame.display.flip()

input()

This is a fully working stand-alone example. The input() is to avoid adding an event-processing loop, but depending how you run the code you may have to Ctl-C out of it.

The program uses the variable nexLine to determine where to display the next line of text, and which gets updated every time you display a line. I don't know what your level of experience is so I've written the code to be easy to read and understand, yet easy to put into a def (nextLine would need to be made global) or as a method inside some kind of dialogue class object (nextLine would be referenced as self.nextLine).

I've also included a nifty little constant named OFFSET. It's set to zero, but the purpose of that is to demonstrate that you can adjust the calculated height of each line you render. You can adjust OFFSET so that the lines are closer together or further apart. I've put it in the program as a constant, but the caveat with using an offset like this is that it varies quite a bit with the size and face of the font. I could be mistaken, but if I remember correctly it is not a linear progression based on font size, and it's different again if you use a different font face.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Hi, first of all thanks for your help but i already solve the problem like some weeks ago. Anyways your code is still useful and i will mark as solution. \$\endgroup\$
    – Furkan125
    Jul 19, 2022 at 14:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .