66

I can't figure out to display text in pygame.
I know I can't use print like in regular Python IDLE but I don't know how.

import pygame, sys
from pygame.locals import *

BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = ( 255, 0, 0)

pygame.init()
size = (700, 500)
screen = pygame.display.set_mode(size)

DISPLAYSURF = pygame.display.set_mode((400, 300))
pygame.display.set_caption('P.Earth')
while 1: # main game loop
    for event in pygame.event.get():
        if event.type == QUIT:           
            pygame.display.update() 

import time

direction = ''
print('Welcome to Earth')
pygame.draw.rect(screen, RED, [55,500,10,5], 0)
time.sleep(1)

This is only the beginning part of the whole program.
If there is a format that will allow me to show the text I type in the pygame window that'd be great. So instead of using print I would use something else. But I don't know what that something else is. When I run my program in pygame it doesn't show anything.
I want the program to run in the pygame window instead of it just running in idle.

Null
  • 1,950
  • 9
  • 30
  • 33
user3146817
  • 697
  • 1
  • 5
  • 9

4 Answers4

80

You can create a surface with text on it. For this take a look at this short example:

pygame.font.init() # you have to call this at the start, 
                   # if you want to use this module.
my_font = pygame.font.SysFont('Comic Sans MS', 30)

This creates a new object on which you can call the render method.

text_surface = my_font.render('Some Text', False, (0, 0, 0))

This creates a new surface with text already drawn onto it. At the end you can just blit the text surface onto your main screen.

screen.blit(text_surface, (0,0))

Bear in mind, that every time the text changes, you have to recreate the surface again, to see the new text.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Bartlomiej Lewandowski
  • 10,771
  • 14
  • 44
  • 75
  • 21
    If you've already called `pygame.init()` in your program, you don't have to call `pygame.font.init()` as well. There's also [`pygame.font.Font`](http://www.pygame.org/docs/ref/font.html#pygame.font.Font) if you want to load the font from a file in your game directory. – skrx Dec 11 '17 at 00:06
  • 2
    If you're on a recent pygame version, use the `freetype` module instead of the `font` module. It's better in every way. – sloth Dec 17 '18 at 12:14
  • 1
    Better use the following to get red text because default background is black and then you can not see anything: textsurface = myfont.render('Some Text', False, (220, 0, 0)) – Sebastian Ax Jan 23 '20 at 20:25
19

There's also the pygame.freetype module which is more modern, works with more fonts and offers additional functionality.

Create a font object with pygame.freetype.SysFont() or pygame.freetype.Font if the font is inside of your game directory.

You can render the text either with the render method similarly to the old pygame.font.Font.render or directly onto the target surface with render_to.

import pygame
import pygame.freetype  # Import the freetype module.


pygame.init()
screen = pygame.display.set_mode((800, 600))
GAME_FONT = pygame.freetype.Font("your_font.ttf", 24)
running =  True

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((255,255,255))
    # You can use `render` and then blit the text surface ...
    text_surface, rect = GAME_FONT.render("Hello World!", (0, 0, 0))
    screen.blit(text_surface, (40, 250))
    # or just `render_to` the target surface.
    GAME_FONT.render_to(screen, (40, 350), "Hello World!", (0, 0, 0))

    pygame.display.flip()

pygame.quit()
skrx
  • 19,980
  • 5
  • 34
  • 48
  • 1
    You are missing argument for antialias and return is not a tuple: `Font.render(text, antialias, color, background=None): return Surface` – Shital Shah Sep 24 '19 at 00:50
9

When displaying I sometimes make a new file called Funk. This will have the font, size etc. This is the code for the class:

import pygame

def text_to_screen(screen, text, x, y, size = 50,
            color = (200, 000, 000), font_type = 'data/fonts/orecrusherexpand.ttf'):
    try:

        text = str(text)
        font = pygame.font.Font(font_type, size)
        text = font.render(text, True, color)
        screen.blit(text, (x, y))

    except Exception, e:
        print 'Font Error, saw it coming'
        raise e

Then when that has been imported when I want to display text taht updates E.G score I do:

Funk.text_to_screen(screen, 'Text {0}'.format(score), xpos, ypos)

If it is just normal text that isn't being updated:

Funk.text_to_screen(screen, 'Text', xpos, ypos)

You may notice {0} on the first example. That is because when .format(whatever) is used that is what will be updated. If you have something like Score then target score you'd do {0} for score then {1} for target score then .format(score, targetscore)

GhostFrag1
  • 987
  • 2
  • 12
  • 19
6

This is slighly more OS independent way:

# do this init somewhere
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
font = pygame.font.Font(pygame.font.get_default_font(), 36)

# now print the text
text_surface = font.render('Hello world', antialias=True, color=(0, 0, 0))
screen.blit(text_surface, dest=(0,0))
Shital Shah
  • 63,284
  • 17
  • 238
  • 185