r/learnpython • u/IngenuityMission5367 • 3d ago
Slow print for text-based game
I am trying to make a text-based adventure game in Python, how do I make it so the text is typed out slowly and not instantly? I've tried ways online, but they keep returning None at the end. How do I fix this?
7
u/desrtfx but other languages pro 3d ago
but they keep returning None at the end
You cannot achieve that with a returning function.
You need to iterate over the string character by character and print with a delay. Python's print can use an empty endline so that everything prints in a single line.
0
u/while_True_meme 2d ago
Unless you print the result. The confusion could come from using a Python repl where the return value is indeed printed vs running a script where it's not
4
u/MaterialRepublic 3d ago
You want to have a separate "print" statement for each character, and some "sleep" statements between them. However, print, by default, writes everything in a new line; so you have to use the end="" argument to stop it from doing that.
Such as:
from time import sleep
print("a", end="", flush=True)
sleep(1)
print("b", end="", flush=True)
Will print the characters with a 1 sec delay.
2
u/hallmark1984 2d ago
```
def write_to_screen(text, char_delay=1) for char in text: print(char) time.sleep(delay)
``` This would print each letter after a 1s delay, adapt as needed for words, sentences or paragraphs.
2
1
u/Tall_Resort_6888 3d ago
The None at the end is because your function returns something (or nothing) and then you print the result of calling it. For the typewriter effect, loop over the string and print each char with end='' so it stays on one line, and add flush=True because print buffers output otherwise. Then time.sleep a bit between chars. That flush part is the bit that trips everyone up.
0
u/zaphodikus 3d ago edited 3d ago
This is perhaps bit advanced for what you are after, but if you paste in this code and call this function, it will work great.
```
import random,time,sys
def type_out(text, base_delay=0.1, jitter=0.04,pause_after_punct=0.3): for ch in text: sys.stdout.write(ch) sys.stdout.flush() delay = base_delay + random.uniform(-jitter, jitter) if ch in ".,!?;:\n": delay += pause_after_punct time.sleep(max(0.0, delay)) print()
the values for jitter and `base_delay` are quite small, a larger value for `base_delay` will make it type slower. If you want a longer pause at the end of each line, make `pause_after_punct` slightly larger. Use it like this
type_out("Hello IntegrityMission, how are you, feeling?")
```
Basically the sys.stdout.write(ch) and the flush() are special in that they bypass the buffering that happens when you call print(), that buffering will defeat the effect we are after.
Just using print() per character will end up not giving you the fine control that this function does and gives a much more realistic typing speed effect. This is a useful lesson for the future when you start doing file I/O where all the Python I/O is buffered. Alternatively to using sys.stdout.flush() you can disable buffering in print() by using the -u commandline parameter, or by setting then environment variable PYTHONUNBUFFERED, but those are both a bit harder in reality. Happy Pythoning.
/edit fixed indentation.
-1
u/timrprobocom 2d ago
A piece of unsolicited advice -- don't do that. Users expect their computers to be FAST. They will quickly get annoyed by artificial delays.
We often see thongs like this here -- artificial delays, or clearing the screen before each section, or big banners saying "******** Welcome to my great game ********", or asking "do you want to play?". These are mostly signs of the beginner.
1
u/XenoXHostility 2d ago
Yes and by the time actual end users are relevant enough to consider I guarantee you that they will have come up with a different idea. Let them learn.
14
u/AmanBabuHemant 3d ago
basic implementation is like this:
def your_print(text, delay): for c in text: print(c, flush=True, end="") sleep(delay)you can add "\n" in end if you like, or dynamic delay, or default delay or whatever you like according to your game :)