【问题标题】:How can I use a class to shrink this code section in Pygame?如何在 Pygame 中使用类来缩小此代码段?
【发布时间】:2021-06-11 19:46:27
【问题描述】:

我正在尝试制作 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'

【问题讨论】:

  • 我很抱歉,但是:but isn't working 不是问题。似乎是什么问题?
  • 请使用完整的错误回溯更新您的question
  • 我做到了,谢谢你的信息。
  • 我不确定你的意思。你想减少什么?
  • @Rabbid76 我的意思是,行中有很多重复,我不能做点什么来避免这种情况吗?

标签: python class pygame


【解决方案1】:

我建议使用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 保存在列表中。使用 list comprehensions 定义字符串列表并创建 Surfaces 列表:

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 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")
# [...]

【讨论】:

    【解决方案2】:

    您可以将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]
    

    【讨论】:

    • 我明白了,您对我可以做些什么来组织或减少它有什么建议吗?
    • 后两个参数是否总是:True, preto? (顺便说一句,preto 是什么?)
    • 'Preto'是颜色black,用来定义字体的颜色,是的,我一直用这两个参数。
    【解决方案3】:

    首先,手头的错误。

    render 似乎是 pygame.font.SysFont 类的一个方法,但是您试图在您的 Fonte 类(类型本身,而不是实例!)上调用它,它没有定义它,所以 Python 有不知道该怎么做并抱怨。为了让你的类做你在编写它时可能想要的意思,你应该继承SysFont(以及它的render定义)或自己定义一个合适的render方法,然后创建一个实例并调用该方法。

    除此之外,您的Tela 类尝试在一个方法上调用__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 或@987654335,则很容易缩小@:

    # 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 循环是列表推导的教科书案例,但我发现对于初学者来说,好的旧循环更容易理解。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-30
      • 1970-01-01
      • 1970-01-01
      • 2010-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多