如何使用 pygame 显示带有字体和颜色的文本?

2024-12-19 09:23:00
admin
原创
61
摘要:问题描述:有没有办法使用 python 在 pygame 窗口上显示文本?我需要显示一堆更新的实时信息,而不想为我需要的每个角色制作一张图片。我可以将文本传输到屏幕上吗?解决方案 1:是的。可以在 pygame 中绘制文本:# initialize font; must be called after 'py...

问题描述:

有没有办法使用 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.Fontrender()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

IT科技

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

IT科技

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

希望这能帮到大家!干杯!

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   990  
  在项目管理领域,CDCP(Certified Data Center Professional)认证评审是一个至关重要的环节,它不仅验证了项目团队的专业能力,还直接关系到项目的成功与否。在这一评审过程中,沟通技巧的运用至关重要。有效的沟通不仅能够确保信息的准确传递,还能增强团队协作,提升评审效率。本文将深入探讨CDCP...
华为IPD流程   26  
  IPD(Integrated Product Development,集成产品开发)是一种以客户需求为核心、跨部门协同的产品开发模式,旨在通过高效的资源整合和流程优化,提升产品开发的成功率和市场竞争力。在IPD培训课程中,掌握关键成功因素是确保团队能够有效实施这一模式的核心。以下将从五个关键成功因素展开讨论,帮助企业和...
IPD项目流程图   27  
  华为IPD(Integrated Product Development,集成产品开发)流程是华为公司在其全球化进程中逐步构建和完善的一套高效产品开发管理体系。这一流程不仅帮助华为在技术创新和产品交付上实现了质的飞跃,还为其在全球市场中赢得了显著的竞争优势。IPD的核心在于通过跨部门协作、阶段性评审和市场需求驱动,确保...
华为IPD   26  
  华为作为全球领先的通信技术解决方案提供商,其成功的背后离不开一套成熟的管理体系——集成产品开发(IPD)。IPD不仅是一种产品开发流程,更是一种系统化的管理思想,它通过跨职能团队的协作、阶段评审机制和市场需求驱动的开发模式,帮助华为在全球市场中脱颖而出。从最初的国内市场到如今的全球化布局,华为的IPD体系在多个领域展现...
IPD管理流程   53  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用