How to Center Text in Pygame
Question:
I have some code:
# draw text
font = pygame.font.Font(None, 25)
text = font.render("You win!", True, BLACK)
screen.blit(text, [SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2])
How can I get the text’s width and height, so I can center text like this:
screen.blit(text, [SCREEN_WIDTH / 2 - text_w / 2, SCREEN_HEIGHT / 2 - text_h / 2])
If this is not possible, what is another way ?
I’ve found this example, but I didn’t really understand it.
Answers:
You can get the dimensions of the rendered text image using text.get_rect()
, which returns a Rect object with width
and height
attributes, among others (see the linked documentation for a full list). I.e. you can simply do text.get_rect().width
.
Rendered text is blitted on a transparent surface in Pygame. So you can use the methods of the surface class described here:
http://www.pygame.org/docs/ref/surface.html#pygame.Surface.get_width
So for you the following would work:
text.get_width()
text.get_height()
You can always just center the text rectangle when you grab it:
# draw text
font = pygame.font.Font(None, 25)
text = font.render("You win!", True, BLACK)
text_rect = text.get_rect(center=(SCREEN_WIDTH/2, SCREEN_HEIGHT/2))
screen.blit(text, text_rect)
just another option
To simplify the use of text, I use this function (to center it the x is not useful)
import pygame
pygame.init()
WIDTH = HEIGHT = 500
screen = pygame.display.set_mode((WIDTH, HEIGHT))
font = pygame.font.SysFont("Arial", 14)
def write(text, x, y, color="Coral",):
text = font.render(text, 1, pygame.Color(color))
text_rect = text.get_rect(center=(WIDTH//2, y))
return text, text_rect
text, text_rect = write("Hello", 10, 10) # this will be centered anyhow, but at 10 height
loop = 1
while loop:
for event in pygame.event.get():
if event.type == pygame.QUIT:
loop = 0
screen.blit(text, text_rect)
pygame.display.update()
pygame.quit()
pygame.Surface.get_rect.get_rect()
returns a rectangle with the size of the Surface object, that always starts at (0, 0) since a Surface object has no position. The position of the rectangle can be specified by a keyword argument. For example, the center of the rectangle can be specified with the keyword argument center
. These keyword argument are applied to the attributes of the pygame.Rect
before it is returned (see pygame.Rect
for a full list of the keyword arguments).
Get the text rectangle and place the center of the text rectangle on the center of the window rectangle:
text_rect = text.get_rect(center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2))
You can even get the center of the window from the display Surface :
text_rect = text.get_rect(center = screen.get_rect().center)
Or with the use of pygame.display.get_surface()
:
text_rect = text.get_rect(center = pygame.display.get_surface().get_rect().center)
A Surface can be drawn on another Surface using the blit
method. The second argument is either a tuple (x, y) representing the upper left corner or a rectangle. With a rectangle, only the upper left corner of the rectangle is taken into account. Therefore you can pass the text rectangle directly to blit
:
screen.blit(text, text_rect)
Minimal example:
import pygame
import pygame.font
pygame.init()
font = pygame.font.SysFont(None, 50)
text = font.render('Hello World', True, (255, 0, 0))
window = pygame.display.set_mode((300, 100))
clock = pygame.time.Clock()
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill(0)
window.blit(text, text.get_rect(center = window.get_rect().center))
pygame.display.flip()
pygame.quit()
exit()
I know I’m late to the party but I recently came across this problem when making a simple python game with pygame so I wanted to share my solution as well.
def draw_text(_window: pygame.Surface, text: str, font: pygame.font.Font, aa: bool, fg: str, bg: str,
x: int | float, y: int | float, centered_x: bool, centered_y: bool) -> None:
"""
Function to draw text on window
:param _window: window to draw text on (pygame.Surface)
:param text: text to draw on window (str)
:param font: font to render the text with (pygame.font.Font)
:param aa: use antialiasing (bool)
:param fg: foreground color (str)
:param bg: background color (str)
:param x: x coordinate of window to draw text on (int | float)
:param y: y coordinate of window to draw text on (int | float)
:param centered_x: center in the x-axis (bool)
:param centered_y: center in the y-axis (bool)
:return: None
"""
text = font.render(text, aa, fg, bg)
text_position = x, y
if centered_x or centered_y:
text_position = text.get_rect()
if centered_x:
text_position.y += y
text_position.centerx = _window.get_rect().centerx
if centered_y:
text_position.x += x
text_position.centery = _window.get_rect().centery
_window.blit(text, text_position)
The function has additional functionality that I explain in the docstring (it can be used for a wide variety of options not just centering x, y axis for text in pygame).
I have some code:
# draw text
font = pygame.font.Font(None, 25)
text = font.render("You win!", True, BLACK)
screen.blit(text, [SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2])
How can I get the text’s width and height, so I can center text like this:
screen.blit(text, [SCREEN_WIDTH / 2 - text_w / 2, SCREEN_HEIGHT / 2 - text_h / 2])
If this is not possible, what is another way ?
I’ve found this example, but I didn’t really understand it.
You can get the dimensions of the rendered text image using text.get_rect()
, which returns a Rect object with width
and height
attributes, among others (see the linked documentation for a full list). I.e. you can simply do text.get_rect().width
.
Rendered text is blitted on a transparent surface in Pygame. So you can use the methods of the surface class described here:
http://www.pygame.org/docs/ref/surface.html#pygame.Surface.get_width
So for you the following would work:
text.get_width()
text.get_height()
You can always just center the text rectangle when you grab it:
# draw text
font = pygame.font.Font(None, 25)
text = font.render("You win!", True, BLACK)
text_rect = text.get_rect(center=(SCREEN_WIDTH/2, SCREEN_HEIGHT/2))
screen.blit(text, text_rect)
just another option
To simplify the use of text, I use this function (to center it the x is not useful)
import pygame
pygame.init()
WIDTH = HEIGHT = 500
screen = pygame.display.set_mode((WIDTH, HEIGHT))
font = pygame.font.SysFont("Arial", 14)
def write(text, x, y, color="Coral",):
text = font.render(text, 1, pygame.Color(color))
text_rect = text.get_rect(center=(WIDTH//2, y))
return text, text_rect
text, text_rect = write("Hello", 10, 10) # this will be centered anyhow, but at 10 height
loop = 1
while loop:
for event in pygame.event.get():
if event.type == pygame.QUIT:
loop = 0
screen.blit(text, text_rect)
pygame.display.update()
pygame.quit()
pygame.Surface.get_rect.get_rect()
returns a rectangle with the size of the Surface object, that always starts at (0, 0) since a Surface object has no position. The position of the rectangle can be specified by a keyword argument. For example, the center of the rectangle can be specified with the keyword argument center
. These keyword argument are applied to the attributes of the pygame.Rect
before it is returned (see pygame.Rect
for a full list of the keyword arguments).
Get the text rectangle and place the center of the text rectangle on the center of the window rectangle:
text_rect = text.get_rect(center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2))
You can even get the center of the window from the display Surface :
text_rect = text.get_rect(center = screen.get_rect().center)
Or with the use of pygame.display.get_surface()
:
text_rect = text.get_rect(center = pygame.display.get_surface().get_rect().center)
A Surface can be drawn on another Surface using the blit
method. The second argument is either a tuple (x, y) representing the upper left corner or a rectangle. With a rectangle, only the upper left corner of the rectangle is taken into account. Therefore you can pass the text rectangle directly to blit
:
screen.blit(text, text_rect)
Minimal example:
import pygame
import pygame.font
pygame.init()
font = pygame.font.SysFont(None, 50)
text = font.render('Hello World', True, (255, 0, 0))
window = pygame.display.set_mode((300, 100))
clock = pygame.time.Clock()
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill(0)
window.blit(text, text.get_rect(center = window.get_rect().center))
pygame.display.flip()
pygame.quit()
exit()
I know I’m late to the party but I recently came across this problem when making a simple python game with pygame so I wanted to share my solution as well.
def draw_text(_window: pygame.Surface, text: str, font: pygame.font.Font, aa: bool, fg: str, bg: str,
x: int | float, y: int | float, centered_x: bool, centered_y: bool) -> None:
"""
Function to draw text on window
:param _window: window to draw text on (pygame.Surface)
:param text: text to draw on window (str)
:param font: font to render the text with (pygame.font.Font)
:param aa: use antialiasing (bool)
:param fg: foreground color (str)
:param bg: background color (str)
:param x: x coordinate of window to draw text on (int | float)
:param y: y coordinate of window to draw text on (int | float)
:param centered_x: center in the x-axis (bool)
:param centered_y: center in the y-axis (bool)
:return: None
"""
text = font.render(text, aa, fg, bg)
text_position = x, y
if centered_x or centered_y:
text_position = text.get_rect()
if centered_x:
text_position.y += y
text_position.centerx = _window.get_rect().centerx
if centered_y:
text_position.x += x
text_position.centery = _window.get_rect().centery
_window.blit(text, text_position)
The function has additional functionality that I explain in the docstring (it can be used for a wide variety of options not just centering x, y axis for text in pygame).