[英]How can I use a class to shrink this code section in Pygame?
我正在尝试制作 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'
您可以将SysFont
的单个实例作为 class 变量:
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]
我建议使用lambda
表达式:
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保存在列表中。 定义字符串列表并使用列表推导创建 Surface 列表:
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]
可以通过订阅访问文本Surfces ( surf_list[0]
, surf_list[1], ...
)。
如果要使用 class 作为字体,请执行以下操作:
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")
# [...]
首先,手头的错误。
render
似乎是pygame.font.SysFont
class 的一种方法,但您正试图在您的Fonte
class 上调用它(类型本身,而不是实例)。 所以 Python 不知道该怎么做并抱怨。 为了让你的 class 做你在编写它时可能想要的意思,你应该继承SysFont
(以及它的render
定义)或自己定义一个合适的render
方法,然后创建一个实例并调用该方法。
除此之外,您的Tela
class 尝试在方法上调用__init__
,这是没有意义的,同时还将该方法传递给Tela
的实例。 那条线是一团糟。
下面是一个固定版本,它应该与您的原始代码相同,但使用类,有点本着给您错误的精神。 我不认为这是一个好主意,事实上我认为考虑到可用的上下文是不合适的。
免责声明:我没有用 PyGame 对此进行测试,我只是用玩具类启动解释器来检查super().__init__(...)
调用。 这应该与您的“之前”代码具有相同的行为,我假设您对此感到满意并做了一些有用的事情。
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
并节省代码和精力。
到你可能想要做的事情上,即在没有一千个fonte.render(...)
行的情况下获得你的“之前”代码的行为。
您的案例看起来很像您想要一些包含相当同质调用结果的变量。 如果您坚持使用单独的变量,无论您如何表达,这都是冗长的,但是如果您接受只有一个变量是某种集合的事实,例如list
或dict
,则很容易缩小:
# 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
循环是列表推导的教科书案例,但我发现好的旧循环对于初学者来说更容易理解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.