Модуль pygame.font

Классы Font и SysFont находятся в модуле pygame.font и предназначены для работы со шрифтами и текстом.

От классов pygame.font.Font и pygame.font.SysFont создаются объекты-шрифты. Второй класс берет системные шрифты, поэтому конструктору достаточно передать имя шрифта. Конструктору Font надо передавать имя файла шрифта. Например:

pygame.font.SysFont('arial', 36)
pygame.font.Font('/usr/share/fonts/truetype/msttcorefonts/Arial.ttf', 36)

Второй аргумент – это размер шрифта в пикселях.

Узнать, какие шрифты есть в системе, можно с помощью функции get_fonts():

>>> pygame.font.get_fonts()
['cmmi10', 'umeminchos3', 'kacstbook', 'freesans', 'lohitpunjabi', ... 

Узнать адрес конкретного шрифта:

>>> pygame.font.match_font('verdana')
'/usr/share/fonts/truetype/msttcorefonts/Verdana.ttf'

Вы можете скопировать шрифт в каталог программы и обращаться к нему без адреса:

pygame.font.Font('Verdana.ttf', 24)

В pygame есть шрифт по-умолчанию. Чтобы использовать его, вместо имени файла в конструктор надо передать объект None:

pygame.font.Font(None, 24)

От обоих классов (Font и SysFont) создаются объекты типа Font.

Метод render() экземпляра Font создает поверхность (экземпляр Surface), на которой "написан" переданный в качестве аргумента текст, шрифтом, к которому применяется метод. Вторым аргументом указывается сглаживание (0 – нет, 1 – есть), третьим – цвет текста. При необходимости четвертым аргументом можно указать цвет фона.

import pygame
pygame.init()
 
sc = pygame.display.set_mode((300,200))
sc.fill((255, 255, 255))
 
f1 = pygame.font.Font(None, 36)
text1 = f1.render('Hello Привет', 1, (180, 0, 0))
 
f2 = pygame.font.SysFont('serif', 48)
text2 = f2.render("World Мир", 0, (0, 180, 0))
 
sc.blit(text1, (10, 50))
sc.blit(text2, (10, 100))
 
pygame.display.update()
 
while 1:
    for i in pygame.event.get():
        if i.type == pygame.QUIT:
            exit()

Текст в Pygame

Рассмотрим такой пример:

import pygame
pygame.init()
 
sc = pygame.display.set_mode((400, 300))
sc.fill((200, 255, 200))
 
font = pygame.font.Font(None, 72)
text = font.render("Hello Wold", 1, (0, 100, 0))
place = text.get_rect(center=(200, 150))
sc.blit(text, place)
 
pygame.display.update()
 
while 1:
    for i in pygame.event.get():
        if i.type == pygame.QUIT:
            exit()
 
    pressed = pygame.key.get_pressed()
    if pressed[pygame.K_LEFT]:
        place.x -= 1
    elif pressed[pygame.K_RIGHT]:
        place.x += 1
 
    sc.fill((200, 255, 200))
    sc.blit(text, place)
 
    pygame.display.update()
 
    pygame.time.delay(20)

Центрирование текста в Pygame

Вспомним, что метод get_rect() экземпляра Surface возвращает объект типа Rect, чьи размеры соответствуют размерам поверхности.

Поскольку у самой поверхности нет собственных свойств-координат на родительском окне, а у Rect они есть, то по умолчанию, если get_rect() применяется без аргументов, для его верхнего левого угла устанавливаются координаты (0, 0).

В нашем примере мы передаем в get_rect() значение для свойства center порождаемой прямоугольной области. Это свойство определяет координаты центра экземпляра Rect (то, что это еще и центр главного окна, неважно). При этом остальные координаты, в том числе координаты верхнего левого угла, вычисляются автоматически, исходя из установленного центра и размеров поверхности.

Поэтому, когда вызывается метод blit(), в который в качестве второго аргумента передается созданный экземпляр Rect, то из последнего берутся координаты верхнего левого угла. Но они уже не (0, 0), а имеют значения, которые равны свойству centerx минус половина ширины и centery минус половина высоты прямоугольной области или соответствующей ей поверхности.

При зажиме стрелок на клавиатуре координата x прямоугольника меняется. В результате метод blit() рисует поверхность в новых координатах.

Практическая работа

У объектов Rect есть метод contains(), который проверяет, заключает ли в себе одна область (к которой применяется метод) другую (которая передается в качестве аргумента).

Напишите программу, в которой, если одна дочерняя поверхность попадает в пределы другой, то на главной поверхности появляется какая-либо надпись. "Подвижный" экземпляр Surface должен переноситься с помощью мыши.

Курс с примерами решений практических работ: android-приложение, pdf-версия.

Комментарии

На решение ушло несколько часов. В основном изучение документации.
В общем как-то так :)
import pygame
pygame.init()
 
FPS = 10
H, W = 500, 500
font = pygame.font.Font(pygame.font.match_font('dejavusans'), 36)
 
WHITE = (255, 255, 255)
BLACK = (50, 50, 50)
GREEN = (0, 255, 0)
 
sc = pygame.display.set_mode((H,W))
pygame.mouse.set_visible(False)
clock = pygame.time.Clock()
 
x, y = 0, 0
text1 = font.render('Hello world', 1, (180,0,0))
 
surf_master = pygame.Surface((50, 50))
 
surf_slave = pygame.Surface((100,100))
slave_x = 50
slave_y = 100
slave_rect = pygame.Rect(slave_x, slave_y, surf_slave.get_size()[0], \
                         surf_slave.get_size()[1])
 
while True:
    for i in pygame.event.get():
        if i.type == pygame.QUIT:
            pygame.quit()
            break
 
    master_rect = pygame.Rect(pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1], \
                          surf_master.get_size()[0], surf_master.get_size()[1])
 
    sc.fill(WHITE)
    surf_master.fill(BLACK)
    surf_slave.fill(GREEN)
 
    sc.blit(surf_slave, (slave_x, slave_y))
    sc.blit(surf_master, (pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1]))
 
    if slave_rect.contains(master_rect) == 1:
        sc.blit(text1, (H//3,W//2))
 
    pygame.display.update()
    clock.tick(FPS)

Прошу привести строку примера кода с данным методом. В интернете сигнатур описывает метод но не приводится примеров, к сожалению. Одной строки будет достаточно . Заранее спасибо.

import pygame
#from random import randint   #думал задавать рандомно координаты движушийся поверж-ти
""" Font меняем цвет и шрифт у поверхностей при их совмещении  """
pygame.init()
 
ORANGE = (255, 150, 100)#оранжевый 
WHITE = (255, 255, 255)#белый
S_Ser=(170, 170, 170)#светло-серый
RED = (225, 0, 50)#красный
BLUE = (0, 0, 225)#синий
sc = pygame.display.set_mode((600,500))#создаем окно игры
sc.fill((WHITE))#белый
 
surf1 = pygame.Surface((170,160))#задаем поверхность (экземпляр Surface)
surf1.fill((S_Ser))  # цвет поверх-ти(экземпляр Surface)
X=300#координата х центра (экземпляр Surface)
Y=250#координата y центра (экземпляр Surface)
rect1 = surf1.get_rect(center=(X, Y))#задаем поверх-ть (экземпляр Rect) с координатами центра
f1 = pygame.font.Font(None, 46)# задаем шрифт 
b1='МИШЕНЬ'#текст в начале
b2='ПОПАЛ'#текст в конце
text1 = f1.render(b1 , 1, (RED))#создаем поверх-ть(экземпляр Surface)- текст
 
surf2 = pygame.Surface((100,100))#задаем поверхность 
surf2.fill((ORANGE))#
x=80#координата х центра (экземпляр Surface)
y=70#координата y центра (экземпляр Surface)
rect2 = surf2.get_rect(center=(x,y))#задаем поверх-ть (экземпляр Rect) с координатами центра
f2 = pygame.font.SysFont(None, 48)#использовать шрифт 
text_k = f2.render('КУБ', 0, (BLUE))#создать поверх-ть(экземпляр Surface)
 
surf1.blit(text1, (10, 60))#отрисовать поверх-ть (экземпляр Font текст) с координатами расположения текста
surf2.blit(text_k, (10, 30))#отрисовать поверх-ть (экземпляр Font текст) с координатами расположения текста
 
sc.blit(surf1,rect1)##отрисовать поверх-ть (экземпляр Surface)
sc.blit(surf2,rect2)##отрисовать поверх-ть (экземпляр Surface)
 
pygame.display.update()#обновить окно
 
while 1:
    a=pygame.event.get()
    for i in a:#выключение игры
        if i.type == pygame.QUIT:
            pygame.quit()
    sc.fill((WHITE))#красим все в белый цвет
    if i.type == pygame.MOUSEBUTTONDOWN:#нажатие кнопки мыши(любой)
        #начинаем движение - в данном случае только в одну сторону( при нажатой кнопке)
        rect2.left+=1#увеличиваем координату х перемещающейся поверхности (экземпляр Rect)
        rect2.top+=1#увеличиваем координату y перемещающейся поверхности (экземпляр Rect)
        sc.blit(surf2,rect2)#отрисовать поверх-ть (экземпляр Surface) после изменений
 
        #вводим условие пересечения/совмещения поверхностей 
        if rect2.left>215 and rect2.left<370 and rect2.top>170 and rect2.top<350:#
            surf1.fill((BLUE))#меняем цвет поверхности(экземпляр Surface) в центре
            text1 = f1.render(b2 , 1, (RED))# меняем текст 
            surf1.blit(text1, (10, 60))#отрисовать поверх-ть с новым тестом
            sc.blit(surf1,rect1)#отрисовать поверх-ть (экземпляр Surface)
            sc.blit(surf2,rect2)#отрисовать поверх-ть (экземпляр Surface)
 
#здесь пытался прописать метод contains()б но не получилось( не уверен в синтаксисе)
#        elif rect1.rect.contains(rect2):
#            text1 = f1.render(b2 , 1, (RED))
#            surf1.blit(text1, (10, 60))
#            sc.blit(surf1,rect1)
 
    sc.blit(surf1,rect1)
    sc.blit(surf2,rect2)
    pygame.display.update()
    pygame.time.delay(20)

Ответ на от Алексей

import pygame
""" Font меняем цвет и шрифт у поверхностей при их совмещении  """
pygame.init()
 
ORANGE = (255, 150, 100)#оранжевый 
WHITE = (255, 255, 255)#белый
S_Ser=(170, 170, 170)#светло-серый
RED = (225, 0, 50)#красный
BLUE = (0, 0, 225)#синий
sc = pygame.display.set_mode((600,500))#создаем окно игры
sc.fill((WHITE))#белый
pygame.mouse.set_visible(False)
 
surf1 = pygame.Surface((170,160))#задаем поверхность (экземпляр Surface)
surf1.fill((S_Ser))  # цвет поверх-ти(экземпляр Surface)
X=300#координата х центра (экземпляр Surface)
Y=250#координата y центра (экземпляр Surface)
rect1 = surf1.get_rect(center=(X, Y))#задаем поверх-ть (экземпляр Rect) с координатами центра
f1 = pygame.font.Font(None, 46)# задаем шрифт 
b1='МИШЕНЬ'#текст в начале
b2='ПОПАЛ'#текст в конце
text1 = f1.render(b1 , 1, (RED))#создаем поверх-ть(экземпляр Surface)- текст
 
surf2 = pygame.Surface((90,80))#задаем поверхность 
surf2.fill((ORANGE))#цвет движущийся поверх-ти
surf2.set_alpha(150)# задаем прозрачность этой поверх-ти
x=80#координата х центра (экземпляр Surface)
y=70#координата y центра (экземпляр Surface)
rect2 = surf2.get_rect(center=(x,y))#задаем поверх-ть (экземпляр Rect) с координатами центра
f2 = pygame.font.SysFont(None, 48)#использовать шрифт 
text_k = f2.render('КУБ', 0, (BLUE))#создать поверх-ть(экземпляр Surface)
 
surf1.blit(text1, (10, 60))#отрисовать поверх-ть (экземпляр Font текст) с координатами расположения текста
surf2.blit(text_k, (10, 30))#отрисовать поверх-ть (экземпляр Font текст) с координатами расположения текста
 
sc.blit(surf1,rect1)##отрисовать поверх-ть (экземпляр Surface)
sc.blit(surf2,rect2)##отрисовать поверх-ть (экземпляр Surface)
 
pygame.display.update()#обновить окно
 
while 1:
    a=pygame.event.get()
    for i in a:#выключение игры
        if i.type == pygame.QUIT:
            pygame.quit()
    sc.fill((WHITE))#красим все в белый цвет
    if pygame.mouse.get_focused():#привязываем к курсору мыши движущуюся поверх-ть
        x,y = pygame.mouse.get_pos()#координаты курсора
        rect2 = surf2.get_rect(center=(x,y))#задаем поверх-ть (экземпляр Rect) с координатами центра
        sc.blit(surf2,rect2)#отрисовать поверх-ть (экземпляр Surface)
 
        if rect1.contains(rect2):#если поверхности накладываются
            surf1.fill((RED)) #меняем цвет поверх-ти на которую попала другая поверхность
            text1 = f1.render(b2 , 1, (0,0,0))#меняем цвет шрифта текста
            surf1.blit(text1, (10, 60))#отрисовать поверх-ть (экземпляр Font текст) с координатами расположения
            sc.blit(surf1,rect1)##отрисовать поверх-ть (экземпляр Surface)
            sc.blit(surf2,rect2)##отрисовать поверх-ть (экземпляр Surface)
        elif rect1.contains(rect2)==0:#если поверхности не накладываются
            surf1.fill((S_Ser)) #возвращаем цвет какой был
            text1 = f1.render(b1 , 1, (RED))#возвращаем цвет шрифта
            surf1.blit(text1, (10, 60))#отрисовать поверх-ть (экземпляр Font текст) с координатами расположения
            sc.blit(surf1,rect1)##отрисовать поверх-ть (экземпляр Surface)
            sc.blit(surf2,rect2)##отрисовать поверх-ть (экземпляр Surface)
 
    sc.blit(surf1,rect1)#отрисовать поверх-ть (экземпляр Surface)
    sc.blit(surf2,rect2)#отрисовать поверх-ть (экземпляр Surface)
    pygame.display.update()#обновить
    pygame.time.delay(20)#задаем кол-во миллисекунд для обновления экрана

Ответ на от Алексей

import pygame
pygame.init()
 
FPS = 10
H, W = 500, 500
font = pygame.font.Font(pygame.font.match_font('dejavusans'), 36)
 
WHITE = (255, 255, 255)
BLACK = (50, 50, 50)
GREEN = (0, 255, 0)
 
sc = pygame.display.set_mode((H,W))
clock = pygame.time.Clock()
 
x, y = 0, 0
text1 = font.render('Hello world', 1, (180,0,0))
 
surf_master = pygame.Surface((50, 50))
 
surf_slave = pygame.Surface((100,100))
slave_x = 50
slave_y = 100
slave_rect = pygame.Rect(slave_x, slave_y, surf_slave.get_size()[0], \
                         surf_slave.get_size()[1])
 
while True:
    for i in pygame.event.get():
        if i.type == pygame.QUIT:
            exit()
 
    sc.fill(WHITE)
    surf_slave.fill(GREEN)
 
    sc.blit(surf_slave, (slave_x, slave_y))
    pos = pygame.mouse.get_pos()
 
    if slave_rect.collidepoint(pos):
        sc.blit(text1, (H//3,W//2))
 
    pygame.display.update()
    clock.tick(FPS)