我有一些问题在pygame中将多行文本渲染到精灵上。文本从txt文件中读取,然后显示在由以下Text类生成的sprite上。但是,由于pygame没有正确渲染多行,我让注释部分按照应该显示的方式显示文本中的每个单词,没有意识到根据我设置的方式,我需要在这个Text类中有一个图像。 (是的,实际上需要。) 我的问题是 有没有办法让我注释掉的部分创建的最终产品进入self.image,好像它是一个像我以前的文本界面一样的表面?
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组的一部分,因此它确实需要图像,也许有一种方法可以在绘制它的同时以某种方式隐藏Text类?
要传递文本,我使用
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')
我希望这能解决问题吗?
答案 0 :(得分:1)
要在曲面上显示多条线,您需要先确定文本的大小。
在下面的示例中,我将字符串列表传递给Text
类。
然后我找到最长行max(font.size(line)[0] for line in self.text)
的宽度和行高font.get_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()