For a certain game I'm making, I think it would look a lot better if each letter came one by one, rather than all at once. What can I do to do this?
2 Answers
First thought:
You could create an animation function:
This could be a loop that goes through each of the characters and displays them. The only real problem with this is the interrupt time in the main thread--pygame's--slowing down the rest of the game's logic.
Better allternative
An alternative would be rendering letters as though they were sprites and moving them on one by one--by setting their motion, this removes the delay.

- 146
- 9
You can do this pretty easily with an iterator. Just create an iterator from the original text, call next(iterator)
to get the next characters and add one after the other to a string variable until its length is equal to the length of the original string.
To restart the animation or display another text, create a new iterator text_iterator = iter(text_orig)
and set text = ''
again.
I also use the ptext
library here because it is able to recognize newline characters to create multiline text.
import pygame as pg
import ptext
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
BG_COLOR = pg.Color('gray12')
BLUE = pg.Color('dodgerblue')
# Triple quoted strings contain newline characters.
text_orig = """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."""
# Create an iterator so that we can get one character after the other.
text_iterator = iter(text_orig)
text = ''
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
# Press 'r' to reset the text.
elif event.type == pg.KEYDOWN:
if event.key == pg.K_r:
text_iterator = iter(text_orig)
text = ''
if len(text) < len(text_orig):
# Call `next(text_iterator)` to get the next character,
# then concatenate it with the text.
text += next(text_iterator)
screen.fill(BG_COLOR)
ptext.draw(text, (10, 10), color=BLUE) # Recognizes newline characters.
pg.display.flip()
clock.tick(60)
pg.quit()
An alternative would be to slice the string:
i = 0 # End position of the string.
done = False
while not done:
# ...
i += 1.5 # You can control the speed here.
screen.fill(BG_COLOR)
ptext.draw(text_orig[:int(i)], (10, 10), color=BLUE)
To restart this, you just need to set i = 0
.

- 19,980
- 5
- 34
- 48
-
this works fine, but if you redisplay the text, it wont pan. It will display, but like normal text.(for my case, if you talk to an npc, the text only pans once, the rest of the time, it will instanlty show up). how can i fix this? – Budderman18 Nov 25 '18 at 01:39
-
You just need to reset `text_iterator = iter(text_orig)` (or pass another string) and `text = ''` or in the slice variant `i = 0`. – skrx Nov 25 '18 at 15:58
-
By the way, to control the speed of the first variant you would have to use a [timer](https://stackoverflow.com/questions/30720665/countdown-timer-in-pygame). The second variant is actually easier to use (I'd only stop the slicing when the text is complete). – skrx Nov 25 '18 at 20:24
-
Have you accepted and unaccepted the answer? Let me know if you need more help. – skrx Nov 25 '18 at 23:38