如何使用 pygame 显示带有字体和颜色的文本?
- 2024-12-19 09:23:00
- admin 原创
- 61
问题描述:
有没有办法使用 python 在 pygame 窗口上显示文本?
我需要显示一堆更新的实时信息,而不想为我需要的每个角色制作一张图片。
我可以将文本传输到屏幕上吗?
解决方案 1:
是的。可以在 pygame 中绘制文本:
# initialize font; must be called after 'pygame.init()' to avoid 'Font not Initialized' error
myfont = pygame.font.SysFont("monospace", 15)
# render text
label = myfont.render("Some text!", 1, (255,255,0))
screen.blit(label, (100, 100))
解决方案 2:
您可以通过使用pygame.font.Font设置字体路径来使用自己的自定义字体
pygame.font.Font(filename, size): return Font
例子:
pygame.font.init()
font_path = "./fonts/newfont.ttf"
font_size = 32
fontObj = pygame.font.Font(font_path, font_size)
然后使用 fontObj.render 将字体渲染到表面,如上面 veiset 的回答所示。:)
解决方案 3:
我的游戏中有一些显示实时得分的代码。它位于一个快速访问函数中。
def texts(score):
font=pygame.font.Font(None,30)
scoretext=font.render("Score:"+str(score), 1,(255,255,255))
screen.blit(scoretext, (500, 457))
我在 while 循环中这样调用它:
texts(score)
解决方案 4:
有两种可能性。无论哪种情况,PyGame 都必须通过 进行初始化pygame.init
。
import pygame
pygame.init()
使用模块pygame.font
并创建一个pygame.font.SysFont
或对象pygame.font.Font
。render()
将pygame.Surface
文本和 Surface 添加blit
到屏幕上:
my_font = pygame.font.SysFont(None, 50)
text_surface = myfont.render("Hello world!", True, (255, 0, 0))
screen.blit(text_surface, (10, 10))
或者使用pygame.freetype
模块。创建一个pygame.freetype.SysFont()
或pygame.freetype.Font
对象。将render()
文本pygame.Surface
或直接将render_to()
文本显示到屏幕上:
my_ft_font = pygame.freetype.SysFont('Times New Roman', 50)
my_ft_font.render_to(screen, (10, 10), "Hello world!", (255, 0, 0))
另请参阅文本和字体
最小pygame.font
示例:![IT科技](https://i.sstatic.net/5jD0C.png) repl.it/@Rabbid76/PyGame-Text
import pygame
pygame.init()
window = pygame.display.set_mode((500, 150))
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 100)
text = font.render('Hello World', True, (255, 0, 0))
background = pygame.Surface(window.get_size())
ts, w, h, c1, c2 = 50, *window.get_size(), (128, 128, 128), (64, 64, 64)
tiles = [((x*ts, y*ts, ts, ts), c1 if (x+y) % 2 == 0 else c2) for x in range((w+ts-1)//ts) for y in range((h+ts-1)//ts)]
for rect, color in tiles:
pygame.draw.rect(background, color, rect)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.blit(background, (0, 0))
window.blit(text, text.get_rect(center = window.get_rect().center))
pygame.display.flip()
pygame.quit()
exit()
最小pygame.freetype
示例:![IT科技](https://i.sstatic.net/5jD0C.png) repl.it/@Rabbid76/PyGame-FreeTypeText
import pygame
import pygame.freetype
pygame.init()
window = pygame.display.set_mode((500, 150))
clock = pygame.time.Clock()
ft_font = pygame.freetype.SysFont('Times New Roman', 80)
background = pygame.Surface(window.get_size())
ts, w, h, c1, c2 = 50, *window.get_size(), (128, 128, 128), (64, 64, 64)
tiles = [((x*ts, y*ts, ts, ts), c1 if (x+y) % 2 == 0 else c2) for x in range((w+ts-1)//ts) for y in range((h+ts-1)//ts)]
for rect, color in tiles:
pygame.draw.rect(background, color, rect)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.blit(background, (0, 0))
text_rect = ft_font.get_rect('Hello World')
text_rect.center = window.get_rect().center
ft_font.render_to(window, text_rect.topleft, 'Hello World', (255, 0, 0))
pygame.display.flip()
pygame.quit()
exit()
解决方案 5:
我编写了一个包装器,它将缓存文本表面,仅在脏时重新渲染。googlecode /ninmonkey/nin.text/demo/
解决方案 6:
我写了一个 TextBox 类。 它可以相对轻松地使用许多自定义字体并指定颜色。我想在屏幕上的几个地方显示文本,其中一些会更新,例如生命、得分(所有玩家的)、最高分、经过的时间等等。
首先,我在项目中创建了一个字体文件夹,并加载了我想要使用的字体。例如,我的 fots 文件夹中有“arcade.ttf”。在创建 TextBox 实例时,我可以使用 fontlocation(可选)参数指定该字体。
例如
self.game_over_text = TextBox("GAME OVER", 100, 80, 420, RED, 'fonts/arcade.ttf')
我发现每次制作文本并更新它都很“笨重”,所以我的解决方案是使用 update_text 方法。
例如,更新玩家得分:
self.score1_text.update_text(f'{self.p1.score}')
它可以重构以接受 str 列表,但它适合我编写“S
# -*- coding: utf-8 -*-
'''
@author: srattigan
@date: 22-Mar-2022
@project: TextBox class example
@description: A generic text box class
to simplify text objects in PyGame
Fonts can be downloaded from
https://www.dafont.com/
and other such sites.
'''
# imports
import pygame
# initialise and globals
WHITE = (255, 255, 255)
pygame.font.init() # you have to call this at the start
class TextBox:
'''
A text box class to simplify creating text in pygame
'''
def __init__(self, text, size, x=50, y=50, color=WHITE, fontlocation=None):
'''
Constuctor
text: str, the text to be displayed
size: int, the font size
x: int, x-position on the screen
y: int, y-position on the screen
color: tuple of int representing color, default is (255,255,255)
fontlocation: str, location of font file. If None, default system font is used.
'''
pygame.font.init()
self.text = text
self.size = size
self.color = color
self.x = x
self.y = y
if fontlocation == None:
self.font = pygame.font.SysFont('Arial', self.size)
else:
self.font = pygame.font.Font(fontlocation, self.size)
def draw(self, screen):
'''
Draws the text box to the screen passed.
screen: a pygame Surface object
'''
text_surface = self.font.render(f'{self.text}', False, self.color)
screen.blit(text_surface, [self.x, self.y])
def update_text(self, new_text):
'''
Modifier- Updates the text variable in the textbox instance
new_text: str, the updated str for the instance.
'''
if not isinstance(new_text, str):
raise TypeError("Invalid type for text object")
self.text = new_text
def set_position(self, x, y):
'''
Modifier- change or set the position of the txt box
x: int, x-position on the screen
y: int, y-position on the screen
'''
self.x = x
self.y = y
def __repr__(self):
rep = f'TextBox instance,
text: {self.text}
FontFamly:{self.font}
Color: {self.color}
Size: {self.size}
Pos: {self.x, self.y}'
return rep
if __name__ == "__main__":
test = TextBox("Hello World", 30, 30, 30)
print(test)
在我的游戏课中使用它
from textbox import TextBox
在游戏的初始化部分,类似这样的事情:
self.time_text = TextBox("Time Left: 100", 20, 20, 40)
self.cred_text = TextBox("created by Sean R.", 15, 600, 870)
self.score1_text = TextBox("0", 100, 40, 650)
self.score2_text = TextBox("0", 100, 660, 650)
self.lives1_text = TextBox("[P1] Lives: 3", 20, 40, 750)
self.lives2_text = TextBox("[P2] Lives: 3", 20, 660, 750)
self.game_over_text = TextBox("GAME OVER", 100, 80, 420, RED)
self.textbox_list = []
self.textbox_list.append(self.time_text)
self.textbox_list.append(self.cred_text)
self.textbox_list.append(self.score1_text)
self.textbox_list.append(self.score2_text)
self.textbox_list.append(self.lives1_text)
self.textbox_list.append(self.lives2_text)
这样当我想在屏幕上绘制所有内容时:
for txt in self.textbox_list:
txt.draw(screen)
在游戏的更新部分,我仅使用 update_text 方法直接更新已更新文本的框 - 如果没有任何内容需要更新,则文本保持不变。
解决方案 7:
我编写了一个TextElement
类来处理文本放置。它仍有改进空间。需要改进的一件事是使用 SysFont 添加后备字体,以防字体资源不可用。
import os
from typing import Tuple, Union
from pygame.font import Font
from utils.color import Color
class TextElement:
TEXT_SIZE = 50
def __init__(self, surface, size=TEXT_SIZE, color=Color('white'), font_name='Kanit-Medium') -> None:
self.surface = surface
self._font_name = font_name
self._size = size
self.color = color
self.font = self.__initialize_font()
@property
def font_name(self):
return self._font_name
@font_name.setter
def font_name(self, font_name):
self._font_name = font_name
self.font = self.__initialize_font()
@font_name.deleter
def font_name(self):
del self._font_name
@property
def size(self):
return self._size
@size.setter
def size(self, size):
self._size = size
self.font = self.__initialize_font()
@size.deleter
def size(self):
del self._size
def write(self, text: str, coordinates: Union[str, Tuple[int, int]] = 'center'):
rendered_text = self.font.render(text, True, self.color)
if isinstance(coordinates, str):
coordinates = self.__calculate_alignment(rendered_text, coordinates)
self.surface.blit(rendered_text, coordinates)
return self
def __calculate_alignment(self, rendered_text, alignment):
# https://www.pygame.org/docs/ref/surface.html#pygame.Surface.get_rect
# Aligns rendered_text to the surface at the given alignment position
# e.g: rendered_text.get_rect(center=self.surface.get_rect().center)
alignment_coordinates = getattr(self.surface.get_rect(), alignment)
return getattr(rendered_text, 'get_rect')(**{alignment: alignment_coordinates}).topleft
def __initialize_font(self):
return Font(os.path.join(
'assets', 'fonts', f'{self._font_name}.ttf'), self._size)
使用方法如下:
TextElement(self.screen, 80).write('Hello World!', 'midtop')
TextElement(self.screen).write('Hello World 2!', (250, 100))
# OR
text = TextElement(self.screen, 80)
text.size = 100
text.write('Bigger text!', (25, 50))
text.write('Bigger text!', 'midbottom')
希望这能帮到大家!干杯!
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理必备:盘点2024年13款好用的项目管理软件