2

I am writing codes which search program with pygame, wikipedia

This is part of my codes

display = pygame.display.set_mode((420, 990))

sem = pygame.font.Font("fonts.ttf", 30)

def write(msg, color, x, y):
    surface = sem.render(msg, True, color)
    display.blit(surface, (x,y))

then, I can render text. and next, Type words what I want to get information in wikipedia(code skip): and get information in wikipedia(next line) result = wikipedia.summary(search, sentences=2)

but if i write long sentence, the result is like this: enter image description here

The sentence is cutted. So, I want this result like this:

Previous

Stack Overflow is a privately held website, the fl

Desired result

Stack Overflow is a privately held website, the flow(sentence continue)

How can I line break in pygame? (But I don't know sentence length

sloth
  • 99,095
  • 21
  • 171
  • 219

1 Answers1

2

Here's a running example (using the word_wrap function from the documentation):

import pygame
import pygame.freetype
pygame.init()

screen = pygame.display.set_mode((100, 200))
running = True

def word_wrap(surf, text, font, color=(0, 0, 0)):
    font.origin = True
    words = text.split(' ')
    width, height = surf.get_size()
    line_spacing = font.get_sized_height() + 2
    x, y = 0, line_spacing
    space = font.get_rect(' ')
    for word in words:
        bounds = font.get_rect(word)
        if x + bounds.width + bounds.x >= width:
            x, y = 0, y + line_spacing
        if x + bounds.width + bounds.x >= width:
            raise ValueError("word too wide for the surface")
        if y + bounds.height - bounds.y >= height:
            raise ValueError("text to long for the surface")
        font.render_to(surf, (x, y), None, color)
        x += bounds.width + space.width
    return x, y

font = pygame.freetype.SysFont('Arial', 20)

while running:
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            running = False
    screen.fill((255, 255, 255))
    word_wrap(screen, 'Hey, this is a very long text! Maybe it is too long... We need more than one line!', font)
    pygame.display.update()

Result:

result

Note how this code uses the pygame.freetype module instead of pygame.font, since it offers such nice functions as Font.render_to and Font.get_rect.

sloth
  • 99,095
  • 21
  • 171
  • 219
  • Hmm, I am still have an error in font.origin, "AttributeError: 'str' object has no attribute 'origin'. Note that: I am using python 3.6.3 – RV3000 Developer Sep 06 '18 at 15:32
  • Sorry to say, Can I ask one more question? I solved the above problem, but I am still one more error. It said, AttributeError: "tuple" object has no attriubte "split" in words = text.split(" ") – RV3000 Developer Sep 07 '18 at 07:33
  • @sloth when I run the example, a `ValueError: text to long for the surface` gets raised. Does it work for you? I'll try to debug it later. – skrx Sep 07 '18 at 12:45
  • @RV3000Developer you have to pass a string as the `text` argument instead of a tuple. – skrx Sep 07 '18 at 12:46
  • @skrx The text is split into words, and that exception happens when the word is too large for the surface. – sloth Sep 07 '18 at 12:49
  • Yes, but why does it raise an exception for me with the same settings as in your example? Are our font sizes or the resolution different? `pygame.freetype.get_default_resolution()` returns 72. – skrx Sep 07 '18 at 13:51
  • @skrx returns `72` for me as well (using pygame 1.9.4, Python 2.7.11, 64-bit Windows). I guess you could add something like `print word, bounds, height, y` after `bounds = font.get_rect(word)` to see where the problem is – sloth Sep 07 '18 at 14:12
  • For `'Hello'` it prints `Hello 200 25`. I'm using pygame 1.9.4, Python 3.7 (also checked out 3.5) and 64-bit Windows as well. – skrx Sep 07 '18 at 14:52