如何在Pygame中使用类来收缩此代码段?

2024-09-30 14:17:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试制作5个屏幕来显示关于一个团队的信息,并且需要在每个屏幕上打印一些文本。我怎样才能避免所有这些线路

fonte = pygame.font.SysFont('Times New Roman', 20)

nomeEquipe = fonte.render("Nome da Equipe", True, preto)
nomeDavid = fonte.render("David Waters Teixeira Rodrigues", True, preto)
nomeRafael = fonte.render("Rafael Pereira de Souza", True, preto)
nomeVicente = fonte.render("Vicente de Paulo Vidal Alencar", True, preto)
nomeVictor = fonte.render("Victor Jerrysson Gama Bastos", True, preto)
nomeWillian = fonte.render("Willian Alves Batista", True, preto)
funcaoDavid = fonte.render("Função: menu inicial", True, preto)
funcaoRafael = fonte.render("Função: tela da equipe", True, preto)
funcaoVicente = fonte.render("Função: tela sobre", True, preto)
funcaoVictor = fonte.render("Função: jogo", True, preto)
funcaoWillian = fonte.render("Função: jogo", True, preto)

我试图实现这一点:

class Fonte:

    def __init__(self, fonte, tamanho):
        pygame.font.SysFont.__init__(self)
        self.fonte = fonte
        self.tamanho = tamanho

class Tela:

    def __init__(self, texto, antialias, cor):
        Fonte.render.__init__(self)
        self.texto = texto
        self.antialias = antialias
        self.cor = cor

fonte = Fonte('Times New Roman', 20)
nomeEquipe = Tela("Nome da Equipe", True, preto)

但我收到了这个错误:

Traceback (most recent call last):
File "/home/rafael/teste.py", line 55, in <module>
nomeEquipe = Tela("Nome da Equipe", True, preto)
File "/home/rafael/teste.py", line 45, in __init__
Fonte.render.__init__(self)
AttributeError: type object 'Fonte' has no attribute 'render'

Tags: selftrueinitrenderdafunnometexto
1条回答
网友
1楼 · 发布于 2024-09-30 14:17:37

首先是眼前的错误

render似乎是pygame.font.SysFont类的一个方法,但您试图在没有定义它的Fonte类(类型本身,而不是实例!)上调用它,因此Python不知道该做什么,并且会抱怨。要使类执行编写时可能意味着的操作,您应该继承SysFont(以及它的render定义),或者自己定义一个合适的render方法,然后创建一个实例并调用该方法

除此之外,您的Tela类尝试在方法上调用__init__,这毫无意义,同时还向该方法传递Tela的实例。那条线乱七八糟

下面是一个固定的版本,它应该与您的原始代码相同,但是使用类,这在某种程度上是出于给您带来错误的精神。我不认为这是一个好主意,事实上,鉴于现有的情况,我认为这是不合适的

免责声明:我没有用PyGame测试这一点,我只是用玩具类旋转解释器来检查super().__init__(...)调用。这应该与您的“before”代码具有相同的行为,我假设您对此感到满意,并且做了一些有用的事情

class Fonte(pygame.font.SysFont):
    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)


class Tela:
    def __init__(self, texto, antialias, cor):
        self.texto = texto
        self.antialias = antialias
        self.cor = cor

    def render_with_font(self, fonte):
        return fonte.render(self.texto, self.antialias, self.cor)
        

fonte = Fonte('Times New Roman', 20)
nomeEquipe = Tela("Nome da Equipe", True, preto).render_with_font(fonte)
...

现在,从更实际的角度来看,请注意新类并没有减少我们必须编写的内容!我们本来可以在第一时间使用SysFont,就像在原始版本中一样,并节省了代码和精力

了解您可能想要做的事情,即获取“before”代码的行为,而不需要上千行

您的案例看起来很像您想要一系列包含相当同质调用结果的变量。如果坚持使用单独的变量,无论你怎么说,这都是冗长的,但是如果你接受只有一个变量是某种集合的事实,比如listdict,这就很容易缩小:

# The data must still be declared somewhere, can't reduce this
text_list = [
    'Nome da Equipe',
    'David Waters Teixeira Rodrigues',
    # ...
]
rendered_text_list = []
for text in text_list:
    rendered_text_list.append(fonte.render(text, True, preto))
# nomeEquipe = rendered_text_list[0]
# nomeDavid = rendered_text_list[1]
# and so on, you can use the list instead of variables

最后一个for循环是一个列表理解的教科书案例,但我发现初学者更容易找到好的旧循环

网友
2楼 · 发布于 2024-09-30 14:17:37

我建议使用^{}表达式:

fonte = pygame.font.SysFont('Times New Roman', 20)
fr = lambda t: fonte.render(t, True, preto)

nomeEquipe = fr("Nome da Equipe")
nomeDavid = fr("David Waters Teixeira Rodrigues")
# [...]

但是,我建议将文本Surfaces保存在列表中。定义字符串列表并使用list comprehensions创建曲面列表:

text_list = [
    "Nome da Equipe", 
    "David Waters Teixeira Rodrigues".
    "Rafael Pereira de Souza"
    # [...]
    ]

fonte = pygame.font.SysFont('Times New Roman', 20)
surf_list = [fonte.render(t, True, preto) for t in text_list]

可以通过订阅(surf_list[0]surf_list[1], ...)访问文本Surfces


如果要为字体使用类,请执行以下操作:

class Fonte:
    def __init__(self, fontname, size, antialias, cor):
        self.font = pygame.font.SysFont(fontname, size)
        self.antialias = antialias
        self.cor = cor
    def render(self, t):
        return self.font.render(t, self.antialias, self.cor)

fonte = Fonte('Times New Roman', 20, True, preto)

nomeEquipe = fonte.render("Nome da Equipe")
nomeDavid = fonte.render("David Waters Teixeira Rodrigues")
# [...]
网友
3楼 · 发布于 2024-09-30 14:17:37

可以将SysFont的单个实例作为类变量:


class Tela:
    fonte = pygame.font.SysFont('Times New Roman', 20)

    def __init__(self, texto, antialias, cor):
        self.surface = Tela.fonte.render(texto, antialias, cor)
        self.texto = texto
        self.antialias = antialias
        self.cor = cor


nomeEquipe = Tela("Nome da Equipe", True, preto)

但是,对于不同的文本,仍然需要所有这些行

但是,如果可以默认最后两个参数:

class Tela:
    fonte = pygame.font.SysFont('Times New Roman', 20)

    def __init__(self, texto, antialias=True, cor=preto):
        self.surface = Tela.fonte.render(texto, antialias, cor)
        self.texto = texto
        self.antialias = antialias
        self.cor = cor

Nomes = ["Nome da Equipe", "David Waters Teixeira Rodrigues", "Rafael Pereira de Souza", "Vicente de Paulo Vidal Alencar", "Victor Jerrysson Gama Bastos", "Willian Alves Batista", "Função: menu inicial", "Função: tela da equipe", "Função: tela sobre", "Função: jogo", "Função: jogo"]

Equipes = [Tela(nome) for nome in Nomes]

相关问题 更多 >