0

I'm writing a basic text-based game with pygame (I'm not too experienced and this is my first question), and I took word-wrapping and animating the letters in a sequence from the two pages in the class docstring and sort of combined them. Right now, the text animates, but if there's a word that should start a new line it doesn't wrap and behaves as it does in the second attachment (duplicates on new line). Wasn't sure what to search online for this. Python 3.8.5; pygame 2.1.2.

class DynamicText:
    """
    Displays and word-wraps text.
    https://stackoverflow.com/questions/42014195/rendering-text-with-multiple-lines-in-pygame
    https://stackoverflow.com/questions/31381169/pygame-scrolling-dialogue-text
    """
    def __init__(self, text, pos, font, color=WHITE, autoreset=False):
        self.done = False
        self.font = font
        self.text = text
        self._gen = self.text_generator(self.text)
        self.pos = pos
        self.color= color
        self.autoreset = autoreset
        self.update()
    
    def reset(self):
        self._gen = self.text_generator(self.text)
        self.done = False
        self.update()
        
    def update(self):
        if not self.done:
            try: self.word_wrap()
            except StopIteration: 
                self.done = True
                if self.autoreset: self.reset()
    
    def word_wrap(self):
        words = [word.split(' ') for word in self.text.splitlines()]  # 2D array where each row is a list of words.
        space = self.font.size(' ')[0]  # The width of a space.
        max_width, max_height = textsurface.get_size()
        x, y = self.pos
        for line in words: #This is what actually renders the text!
            word_surface = self.rendered = self.font.render((next(self._gen)), True, self.color) 
            word_width, word_height = word_surface.get_size()
            if x + word_width >= max_width:
                x = self.pos[0]  # Reset the x.
                y += word_height  # Start on new row.
            textsurface.blit(word_surface, (x, y))
            x += word_width + space
        x = self.pos[0]  # Reset the x.
        y += word_height  # Start on new row.
    
    def text_generator(self,text):
            tmp = ""
            for letter in text:
                tmp += letter
                # don't pause for spaces
                if letter != " ":
                    yield tmp
if __name__=='__main__':
    running=True
    ds=DoStuff() #makes screen, textbox, image rect
    msg=DynamicText("Hey, does rendering this work? What about actual multiline text?", (10,10), textdata, WHITE)
    while running:
        screen.blit(textsurface,(20,10))
        screen.blit(imgsurface,(650,10))
        clock.tick(60)
        pg.display.update()
        for event in pg.event.get():
            if event.type==QUIT:
                running=False
            if event.type==pg.USEREVENT:
                msg.update()
    pg.quit()
    sys.exit()

What it does with one line (correct)

What it does with one line (correct)

What it does with text that's supposed to be wrapped (incorrect)

What it does with text that's supposed to be wrapped (incorrect)

Barmar
  • 741,623
  • 53
  • 500
  • 612

1 Answers1

0

you should add the line division from the first question linked in this question. As well as you can use something like this:

body = ['Be careful with your inputs, game does not have good error handling!',
                'To choose who begins the game input "a" for computer or "b" for yourself',
                'Press enter to play']
        label = []
        for line in range(len(body)):
            label.append(word_font.render(body[line], True, yellow)) #creates text lable

        for line in range(len(label)):
            disp.blit(label[line], [display_w / 5, 150 + 25 * line]) #positions the text
Artis
  • 35
  • 5
  • What do you mean by "line division"? Also, what would `display_w` be? – undonepotato Jul 11 '22 at 15:41
  • “line division” wasn’t the best wording, but basically from the linked question you can see the text that has to be displayed is just a long string split by using “\n” which should work. “display_w” is just the display width used to position the text and create space between lines(display_w can be replaced by any value to fit the position of text you need) @undonepotato – Artis Jul 12 '22 at 09:35