Текст и счёт на экране
Очки, жизни, таймер — игре нужно показывать цифры и текст. Шрифты в Pygame рендерят строку в картинку, которую мы рисуем как обычный спрайт.
Суть: текст в Pygame — это картинка. Шрифт через font.render превращает строку в Surface, которую рисуют через blit. Меняется счёт — пересоздаём картинку текста.
Любая игра показывает информацию: счёт, число жизней, время, надпись «Game Over». В Pygame нет привычного «вывести текст» как в консоли — здесь текст это картинка. Мы берём шрифт, говорим ему «нарисуй вот эту строку этим цветом», и получаем Surface — такую же поверхность, как загруженный спрайт. Её рисуем на экране через blit.
Сначала создаём объект шрифта: pygame.font.Font(None, 48) — None означает стандартный системный шрифт, 48 — размер. Затем рендерим: font.render("Счёт: 100", True, (255,255,255)). Второй аргумент True включает сглаживание (antialiasing) — буквы получаются гладкими, а не зубчатыми. Результат — картинка текста, которую можно blit-нуть в любую точку.
Важный момент: текст меняется (счёт растёт), поэтому картинку нужно пересоздавать заново каждый раз, когда значение изменилось. Рендерить каждый кадр можно, но если значение не поменялось — лучше переиспользовать старую картинку, это экономит ресурсы.
Как работает под капотом
Шрифт превращает строку в набор пикселей-букв на прозрачной поверхности. Дальше это обычный blit, как со спрайтом:
"Счёт: 100"
| font.render(text, True, color)
v
[картинка текста] (Surface с буквами)
| screen.blit(img, (x, y))
v
текст на экране
счёт изменился -> render заново -> новая картинка
В pygame (читаем):
pygame.font.init()
font = pygame.font.Font(None, 48) # системный шрифт, размер 48
score = 0
# в цикле, когда рисуем:
text_img = font.render(f"Счёт: {score}", True, (255, 255, 255))
screen.blit(text_img, (20, 20))
# выровнять по центру:
rect = text_img.get_rect(center=(400, 50))
screen.blit(text_img, rect)Форматирование строки счёта — обычный Python, проверяемый без графики. Соберём строки HUD (счёт, жизни, время). Попробуй сам:
def hud_lines(score, lives, seconds):
return [
f"Счёт: {score}",
f"Жизни: {'<3 ' * lives}".strip(),
f"Время: {int(seconds // 60)}:{int(seconds % 60):02d}",
]
for line in hud_lines(score=1250, lives=3, seconds=95):
print(line)Кастомные шрифты и кеширование текста
Системный шрифт (Font(None, 48)) хорош для прототипа, но выглядит казённо. Свой характер игре придаёт шрифт из файла: pygame.font.Font("pixel.ttf", 32) загружает любой TTF, например пиксельный для ретро-аркады. Шрифт — часть стиля игры наравне с цветами и спрайтами, и подобрать его стоит так же тщательно. Один удачный шрифт мгновенно делает интерфейс «своим», а не дефолтным.
Про производительность: рендер текста — операция не бесплатная, она каждый раз заново рисует все буквы. Если счёт меняется редко, глупо рендерить его 60 раз в секунду. Профессиональный приём — кешировать картинку текста и пересоздавать её только тогда, когда значение изменилось: if score != last_score: text_img = font.render(...). Для статичных надписей вроде «Пауза» рендери один раз при старте. Эти мелочи незаметны на простой игре, но входят в привычку и держат FPS высоким, когда интерфейс разрастётся до десятков надписей.
Текст в игре — это не только счёт, но и весь её «голос»: подсказки, диалоги, названия уровней, экраны победы и поражения. Поэтому стоит сразу сделать удобную функцию-помощник, например draw_text(surface, text, pos, size, color), которая рендерит строку и рисует её в нужном месте с нужным выравниванием. Один раз написал — и весь остальной код пишет текст одной короткой строкой, без повторения возни со шрифтом и get_rect. Это та же идея переиспользования, что и со словарём ассетов или константами цветов: вынеси рутину в одно место и пользуйся ей везде. Аккуратная работа с текстом делает интерфейс игры опрятным, а код — компактным и приятным для чтения.
Частые ошибки
- Забыть
font.init()(или общийpygame.init()) — шрифт не создастся. - Рендерить текст до создания строки счёта — увидишь старое значение.
- Передать число вместо строки в render — нужна строка, оборачивай в
str()или f-строку.
Best practices
- Создавай объект
Fontодин раз, переиспользуй каждый кадр. - Для выравнивания используй
get_rect(center=...)— текст встанет ровно. - Если значение не меняется, не рендери его заново каждый кадр.
Итог: текст это картинка из шрифта. render превращает строку в Surface, blit рисует её. Меняется число — пересоздаём картинку.