Pygame 4: fonts and how to center them

Let’s show how to put text into pygame. It’s a bit tricky, so let’s see how to do it. In a recent update of this post I added at the end some code to center the text on the screen, with a couple of methods. Go to read it clicking here if you want to know just that.

Previous edisodes:

Pygame 1 – Starting with Pygame

Pygame 2 – Drawing

Pygame 3 – Moving sprites

Fonts rendering

In this 4th episode of “Pygame” we are gonna talk about fonts. You will have to write something on the screen, right? A score at least. What is a game without scores? To gain a higher score is the reason for the game exists. So, to see fonts you will have to

  • initialize them with pygame.init() or pygame.font.init(), if you do not want to get an error
    • pygame.font.init()
  • initialize a specific a font type with pygame.font.SysFont
    • font = pygame.font.
    • SysFont(“Arial”, 72)
  • then you will render that font type with some txt and color
    • text = font.render(“Start game”, True, (255,255,255)

Furthermore, you will have to do the usual stuff.

  • initialize a SURFACE (the screen on wich we will draw)
    • SURF = pygame.display.set_mode((600, 400))
  • create a loop to display stuffs
    • while loop == True:
  • use blit to display every text rendered(to display the text rendered above in the var text)
    • SURF.blit(text, (100,150))
  • clear the screen at each frame if something moves
    • SURF.fill((0,0,0))
  • Update the screen for each frame
    • pygame.display.update()
  • ensure that you can close the window correctly with this code (for e in pygame.event.get()):
    • if e.type == QUIT: loop = 0

I wanted to make something move nicely, instead of having everything still, so I added a little trick we just used in the previous three episodes, i.e. to link the position of the second text to the mouse.

x, y = pygame.mouse.get_pos()
SURF.blit(restart, (x, y))

So, feel free to move around the mouse to see how the text will gently follow you around the black screen.

Show me some fonts

Here is the code. Save it as something.py and run it with the cmd typing python something.py.

import pygame
from pygame.locals import *

pygame.init()
pygame.font.init()
# font object..................................
def create_font(t,s=72,c=(255,255,0), b=False,i=False):
    font = pygame.font.SysFont("Arial", s, bold=b, italic=i)
    text = font.render(t, True, c)
    return text
# Text to be rendered with create_font    
game_over = create_font("GAME OVER")
restart = create_font("Press Space to restart", 36, (9,0,180))

SURF = pygame.display.set_mode((600, 400))
loop = True
clock = pygame.time.Clock()
while loop == True:
    SURF.fill((0,0,0))
    x, y = pygame.mouse.get_pos()
    SURF.blit(game_over, (100,150))
    SURF.blit(restart, (x, y))
    for e in pygame.event.get():
        if e.type == QUIT:
            loop = 0
    pygame.display.update()
    clock.tick(60)

pygame.quit()

This is the (static) result of the code:This is the dynamic version:

About SysFont

Let’s read what is SysFont typing:

help(pygame.font.SysFont)

Help on function SysFont in module pygame.sysfont: SysFont(name, size, bold=False, italic=False, constructor=None) pygame.font.SysFont(name, size, bold=False, italic=False, constructor=None) -> Font create a pygame Font from system font resources This will search the system fonts for the given font name. You can also enable bold or italic styles, and the appropriate system font will be selected if available. This will always return a valid Font object, and will fallback on the builtin pygame font if the given font is not found. Name can also be a comma separated list of names, in which case set of names will be searched in order. Pygame uses a small set of common font aliases, if the specific font you ask for is not available, a reasonable alternative may be used. if optional contructor is provided, it must be a function with signature constructor(fontpath, size, bold, italic) which returns a Font instance. If None, a pygame.font.Font object is created.

How to center text?

If you want to center text you can make two things:

  • use the get_width and get_height methods from the surface and divide them by two, create a

Initiate pygame, fonts and screen

import pygame
from pygame.locals import *

pygame.init()
pygame.font.init()
SURF = pygame.display.set_mode((600, 400))

Create a function that returns…

This function returns the text rendered and the coordinate of the text in textRect obtained with get_rect()

def create_font(t,s=72,c=(255,255,0), b=False,i=False):
    font = pygame.font.SysFont("Arial", s, bold=b, italic=i)
    text = font.render(t, True, c)
    textRect = text.get_rect()
    return text,textRect

Use the function to create two text with relative ‘textRect’

game_over, gobox = create_font("GAME OVER")
restart, rbox = create_font("Press Space to restart", 36, (9,0,180))

First method to center the first text

The gobox label will point to a Rectangle object that has the center in the middle (centerx and centery that are obtained with SURF.get_width() // 2 and SURF-get_width() // 2.

centerx, centery = SURF.get_width() // 2, SURF.get_height() // 2
gobox = game_over.get_rect(center=(centerx, centery))

This will go in the loop to display the ‘game’ here:

you pass to blit the rendered text (game_over) and the Rectangle in wich the text is contained, centered as we’ve seen above in the gobox object.

SURF.blit(game_over, gobox)

Second method for the second text

This text will be centered only horizontally.

We create a new attribute for the restart rendered text who’s value are a tuple with the centered width and as height you just have the height of the text itself (so that it as the same distance from the top as the height of the text… it’s not centerd vertically, only horizontally, as you can see in the image below. If you wanted to center this text in this way also vertically you should have put as height: SURF.get_height() // 2. I did no do it to avoid writing this text over the first text.

rbox = int((SURF.get_width() - restart.get_width())//2), restart.get_height()

The relative blit function in the loop will be:

SURF.blit(restart, rbox)

Note that in the first method you passed gobox and in this

The loop

loop = True
clock = pygame.time.Clock()
while loop == True:
    SURF.fill((0,0,0))
    x, y = pygame.mouse.get_pos()
    SURF.blit(game_over, gobox)
    SURF.blit(restart, rbox)
    for e in pygame.event.get():
        if e.type == QUIT:
            loop = 0
    pygame.display.update()
    clock.tick(60)

pygame.quit()

The ouput:

Notice the difference with the first image with the same text (just look at Game Over, because the other text was being moved by the mouse, so it was not centered).

Pygame's Platform Game

Other Pygame's posts

Published by pythonprogramming

Started with basic on the spectrum, loved javascript in the 90ies and python in the 2000, now I am back with python, still making some javascript stuff when needed.