Python 似乎无法在sprite上渲染pygame中的多行

Python 似乎无法在sprite上渲染pygame中的多行,python,python-3.x,pygame,text-rendering,pygame-surface,Python,Python 3.x,Pygame,Text Rendering,Pygame Surface,在pygame中,我在将多行文本渲染到精灵上时遇到一些问题。文本从txt文件中读取,然后显示在由以下文本类生成的精灵上。然而,由于pygame没有正确地呈现多行,我让注释部分以应该显示的方式显示文本中的每个单词,没有意识到根据我设置所有内容的方式,我需要在这个文本类中显示一个图像。(是的,确实需要。) 所以我的问题是 有没有办法让我的注释掉的零件创建的最终产品进入self.image,就好像它是一个曲面一样,就像我以前的textsurface一样 class Text(pg.sprite.Spr

在pygame中,我在将多行文本渲染到精灵上时遇到一些问题。文本从txt文件中读取,然后显示在由以下文本类生成的精灵上。然而,由于pygame没有正确地呈现多行,我让注释部分以应该显示的方式显示文本中的每个单词,没有意识到根据我设置所有内容的方式,我需要在这个文本类中显示一个图像。(是的,确实需要。) 所以我的问题是 有没有办法让我的注释掉的零件创建的最终产品进入self.image,就好像它是一个曲面一样,就像我以前的textsurface一样

class Text(pg.sprite.Sprite):
    def __init__(self, game, x, y, text):
        self.groups = game.all_sprites, game.text
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        myfont = pg.font.SysFont('lucidaconsole', 20, bold = True)

        '''words = [word.split(' ') for word in text.splitlines()]
        space = myfont.size(' ')[0]
        max_width = 575
        max_height = 920
        pos = (0, 0)
        text_x, text_y = pos
        for line in words:
            for word in line:
                text_surface = myfont.render(word, False, (0, 255, 0))
                text_width, text_height = text_surface.get_size()
                if (text_x + text_width >= max_width):
                    text_x = pos[0]
                    text_y += text_height
                game.screen.blit(text_surface, (text_x, text_y))
                text_x += text_width + space
            text_x = pos[0]
            text_y += text_height'''

        textsurface = myfont.render(text, False, (0, 255, 0))
        self.image = textsurface
        game.screen.blit(textsurface, (0, 0))
        self.rect = game.text_img.get_rect()
        self.x = x
        self.y = y
        self._layer = 2
        self.rect.x = (x * TILESIZE) - 49
        self.rect.y = (y * TILESIZE) - 45
也许有点模糊,为什么必须这样做,因为游戏的大部分都是这样画的:

def draw(self):
    for sprite in sorted(self.all_sprites, key=lambda s: s._layer):
        self.screen.blit(sprite.image, self.camera.apply(sprite))
    pg.display.flip()
为了能够绘制它,它必须是all_sprites组的一部分,所以它确实需要图像,也许有一种方法可以在仍然绘制它的同时隐藏文本类

为了传递文本,我使用

if event.type == pg.USEREVENT + 1:
            for row, tiles in enumerate(self.map.data):
                for col, tile in enumerate(tiles):
                    if tile == 'T':
                        with open('text_code.txt') as f:
                            for line in f:
                                Text(self, col, row, line)
文本来自一个.txt文件,在这里可以找到如下文本:

Player has moved left!
Player has moved down!
Player has moved down!
Player has moved right!
Player has moved right!
这是由任何玩家运动写在这里的:

def move(self, dx=0, dy=0):
    if (dx == -1):
        with open('text_code.txt', 'a') as f:
            f.write('Player has moved left!\n')
    if (dx == 1):
        with open('text_code.txt', 'a') as f:
            f.write('Player has moved right!\n')
    if (dy == -1):
        with open('text_code.txt', 'a') as f:
            f.write('Player has moved up!\n')
    if (dy == 1):
        with open('text_code.txt', 'a') as f:
            f.write('Player has moved down!\n')

我希望这能把事情弄清楚?

要在一个表面上点几行,你需要先计算出文本的大小

在下面的示例中,我将字符串列表传递给
Text

然后我找到最长线条的宽度
max(font.size(line)[0]表示self.text中的线条)
和线条高度
font.get\u linesize()
并创建一个具有此大小的曲面(通过
pg.SRCALPHA
使其透明)

现在,您可以使用
for
循环来渲染
self.text
列表中的行,并将其blit到曲面上。枚举行列表以获得y位置,并按行高度相互叠加

import pygame as pg


pg.init()

MYFONT = pg.font.SysFont('lucidaconsole', 20, bold=True)

s = """Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum."""


class Text(pg.sprite.Sprite):

    def __init__(self, pos, text, font):
        super().__init__()
        self.text = text
        width = max(font.size(line)[0] for line in self.text)
        height = font.get_linesize()
        self.image = pg.Surface((width+3, height*len(self.text)), pg.SRCALPHA)
        # self.image.fill(pg.Color('gray30'))  # Fill to see the image size.
        # Render and blit line after line.
        for y, line in enumerate(self.text):
            text_surf = font.render(line, True, (50, 150, 250))
            self.image.blit(text_surf, (0, y*height))
        self.rect = self.image.get_rect(topleft=pos)


class Game:

    def __init__(self):
        self.done = False
        self.clock = pg.time.Clock()
        self.screen = pg.display.set_mode((1024, 768))
        text = Text((20, 10), s.splitlines(), MYFONT)
        self.all_sprites = pg.sprite.Group(text)

    def run(self):
        while not self.done:
            self.clock.tick(30)
            self.handle_events()
            self.draw()

    def handle_events(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                self.done = True

    def draw(self):
        self.screen.fill((50, 50, 50))
        self.all_sprites.draw(self.screen)
        pg.display.flip()


if __name__ == '__main__':
    Game().run()
    pg.quit()

嘿,我试过你上面说的,但是我得到了ValueError:max()arg是一个空序列,知道为什么吗?[在width=max(font.size~)部分]不能将空序列(列表、元组等)传递给
max
。它必须包含一些项目
text
在我的示例中是一个字符串列表。我试着这样做“
width=max(myfont.size(line)[0]表示self.text中的line)
猜测不是这样的,我将搜索它应该是什么样子的
text
参数传递了什么?编辑了原始帖子