How to display text in pygame? [duplicate]

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.


Solution 1:

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.
myfont = pygame.font.SysFont('Comic Sans MS', 30)

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

textsurface = myfont.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(textsurface,(0,0))

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

Solution 2:

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()

Solution 3:

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)

Solution 4:

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))