How to display text in pygame? [duplicate] - python

This question already has answers here:
pygame - How to display text with font & color?
(7 answers)
Closed 2 years ago.
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.

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.

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

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)

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

Related

Padding for text using pygame SysFont

I'm trying to use pygame's SysFont to display some text on the screen but I want the background rectangle to be slightly wider than the actual text.
When I use the following code the background seems to start exactly where the first letter starts and finishes exactly where the last letter ends.
font = pygame.font.SysFont("Helvetica", 30)
img = font.render("ABC", True, "white", "blue1")
img_width = img.get_width()
img_height = img.get_height()
screen.blit(img, (200, 200, img_width, img_height))
Is there a way to have some padding to the left and right of the text in the background colour? I thought that perhaps adding something to img_width might help but it didn't.
You need to render the text on Surface larger than the text Surface:
Render the text with a transparent background
Create a Surface larger the the text Surface (see pygame.Rect.inflate)
Fill the Surface with the background color
blit the text in the center of the Surface
Minimal example:
import pygame
pygame.init()
window = pygame.display.set_mode((300, 200))
clock = pygame.time.Clock()
def create_text_box(font, text, text_color, box_color, margin_x, margin_y):
text_surf = font.render("ABC", True, text_color, "blue1")
box_surf = pygame.Surface(text_surf.get_rect().inflate(margin_x, margin_y).size)
box_surf.fill(box_color)
box_surf.blit(text_surf, text_surf.get_rect(center = box_surf.get_rect().center))
return box_surf
font = pygame.font.SysFont(None, 100)
text_surf = create_text_box(font, "ABC", "white", "blue1", 10, 0)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill(0)
window.blit(text_surf, text_surf.get_rect(center = window.get_rect().center))
pygame.display.flip()
clock.tick(60)
pygame.quit()
exit()
See also How to separately change the opacity of a text on a button pygame?

Can't find a way to make multiple lines in pygame

I'm aware of the fact that pygame's screen.blit is not meant to support multiple lines, however I can't figure out a work around. All of the other threads that ask this question just don't work with my code. How do I make this work?
I've tried to split response into two by using splitline() on DisplayRoom.prompt and then having the game just load two lines separately, but DisplayRoom.prompt.splitline() does not turn `DisplayRoom.prompt from a tuple to a list and only returns the value for it.
screen.fill(background_colour)
txt_surface = userfont.render(text, True, color)
screen.blit(txt_surface, (100, 800))
response = promptfont.render(DisplayRoom.prompt, True, color)
screen.blit(response, (80, 300))
pygame.display.flip()
clock.tick_busy_loop(60) # limit FPS
When I defined DisplayRoom.prompt, I expected \n to linebreak it but it doesn't work which is why I'm here.
It is not Surface.blit which doesn't support multiple lines. blit simply draw a Surface on another Surface, it doesn't care what the Surface contains.
It's pygame.Font.render which doesn't support multilines. The docs clearly say:
The text can only be a single line: newline characters are not rendered.
So I don't know what DisplayRoom.prompt is in your code, but if is not a string, is bound to fail: render raises a TypeError: text must be a unicode or bytes.
And if is a string with newlines, newlines are just not rendered.
You have to split the text and render each line separately.
In the following example I create a simple function blitlines which illustrates how you could do.
import sys
import pygame
def blitlines(surf, text, renderer, color, x, y):
h = renderer.get_height()
lines = text.split('\n')
for i, ll in enumerate(lines):
txt_surface = renderer.render(ll, True, color)
surf.blit(txt_surface, (x, y+(i*h)))
background_colour = (0, 0, 0)
textcolor = (255, 255, 255)
multitext = "Hello World!\nGoodbye World!\nI'm back World!"
pygame.init()
screen = pygame.display.set_mode((500, 500))
userfont = pygame.font.Font(None, 40)
screen.fill(background_colour)
blitlines(screen, multitext, userfont, textcolor, 100, 100)
pygame.display.flip()
#main loop
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
This is the result on the screen.

Two Surfaces not bliting pygame

I'm trying to render some font onto my Pygame screen but it never shows up. I think I have everything set-up right and my programs not throwing any errors so I'm not sure what's wrong. This is the code I'm using to try and create the text:
pygame.init()
pygame.display.set_caption("MyGame")
font = SysFont("Times", 24) #Create a new font using times if it exists, else use system font.
white = (255, 255, 255)
while True: #Game loop
label = font.render("Score: " + str(score), 1, white)
self.surface.blit(label, (100, 100))
# Do other game things....
self.board.draw()
pygame.display.update()
self.clock.tick(60)
and in my init function:
def __init__(self):
self.surface = pygame.display.set_mode((400, 500)) #Set dimensions of game window. Creates a Surface
self.clock = pygame.time.Clock()
self.board = Board(self.surface) # Board is an object in my game
What am I doing wrong? I've looked all over the Pygame documentation and SO but I can't see anything wrong in my code. I've also tried setting the font explicitly with
font = pygame.font.Font("/System/Library/Fonts/Helvetica.dfont", 24)
but nothing seems to work.
As furas suggested, the problem was caused by me filling in the surface after drawing.

Displaying text with pygame [duplicate]

This question already has answers here:
How to display text in pygame? [duplicate]
(4 answers)
Closed 9 years ago.
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.circ(screen, RED, [55,500,10,5], 0)
time.sleep(1)
print('Earth was a very prosperous planet. Filled with life and culture.')
time.sleep(2)
This is only a part of it. It doesn't display on the pygame screen. (in case you're wondering i do use pygame.quit() at the end) I just want it to work. If you could make your answers simpler, that'd be great because i'm still a beginner. How would i display the text? any help will do. thanks.
You're looking to use the pygame font module.
Here's an example of rendering then positioning the font on your screen. ()
import pygame.font
font = pygame.font.Font(None, 36) # None can be a font file instead
text = font.render("Welcome to Earth", 1, (0, 0, 0))
# Determine the location that should be allocated for the text
text_box = text.get_rect(centerx=DISPLAYSURF.get_width()/2)
# Draw the text onto the background
background.blit(text, text_box)

How to add text into a pygame rectangle

I have come as far as drawing a rectangle in pygame however I need to be able to get text like "Hello" into that rectangle. How can I do this? (If you can explain it as well that would be much appreciated. Thank-you)
Here is my code:
import pygame
import sys
from pygame.locals import *
white = (255,255,255)
black = (0,0,0)
class Pane(object):
def __init__(self):
pygame.init()
pygame.display.set_caption('Box Test')
self.screen = pygame.display.set_mode((600,400), 0, 32)
self.screen.fill((white))
pygame.display.update()
def addRect(self):
self.rect = pygame.draw.rect(self.screen, (black), (175, 75, 200, 100), 2)
pygame.display.update()
def addText(self):
#This is where I want to get the text from
if __name__ == '__main__':
Pan3 = Pane()
Pan3.addRect()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit(); sys.exit();
Thank you for your time.
You first have to create a Font (or SysFont) object. Calling the render method on this object will return a Surface with the given text, which you can blit on the screen or any other Surface.
import pygame
import sys
from pygame.locals import *
white = (255,255,255)
black = (0,0,0)
class Pane(object):
def __init__(self):
pygame.init()
self.font = pygame.font.SysFont('Arial', 25)
pygame.display.set_caption('Box Test')
self.screen = pygame.display.set_mode((600,400), 0, 32)
self.screen.fill((white))
pygame.display.update()
def addRect(self):
self.rect = pygame.draw.rect(self.screen, (black), (175, 75, 200, 100), 2)
pygame.display.update()
def addText(self):
self.screen.blit(self.font.render('Hello!', True, (255,0,0)), (200, 100))
pygame.display.update()
if __name__ == '__main__':
Pan3 = Pane()
Pan3.addRect()
Pan3.addText()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit(); sys.exit();
Note that your code seems a little bit strange, since usually you do all the drawing in the main loop, not beforehand. Also, when you make heavy use of text in your program, consider caching the result of Font.render, since it is a very slow operation.
Hi!
To be honestly there is pretty good ways to write text in any place of current rect.
And now i'll show how to do it pretty easy.
First of all we need to create object of rect instance:
rect_obj = pygame.draw.rect(
screen,
color,
<your cords and margin goes here>
)
Now rect_obj is object of pygame.rect instance. So, we are free to manipulate with this methods. But, beforehand lets create our rendered text object like this:
text_surface_object = pygame.font.SysFont(<your font here>, <font size here>).render(
<text>, True, <color>
)
Afterall we are free to manipulate with all methods, as i mensioned before:
text_rect = text_surface_object.get_rect(center=rect_obj.center)
What is this code about?
We've just got center cords of out current rect, so easy!
Now, you need to blit ur screen like this:
self.game_screen.blit(text_surface_object, text_rect)
Happy coding! :)

Categories