Maya
Maya

Reputation: 35

How can I make Pygame wait a few milliseconds before every loop in a for loop without stopping other stuff?

I have a for loop in Pygame that is trying to slowly progress through a string, like how text scrolls in RPGs. I want it to wait around 7 milliseconds before displaying the next character in the string, but I don't know how to make the loop wait that long without stopping other stuff. Please note that I am very new to pygame and python in general. Here is my code:

mainText = pygame.font.Font(mainFont, 40)
finalMessage = ""

for letter in msg:
    finalMessage = finalMessage + letter
    renderMainText = mainText.render(finalMessage, True, white)
    screen.blit(renderMainText, (100, 100))
renderMainText = mainText.render(finalMessage, True, white)

Do I need to do threading? Asyncrio?

Upvotes: 2

Views: 142

Answers (2)

Rabbid76
Rabbid76

Reputation: 210890

You don't need the for loop at all. You have an application loop, so use it. The number of milliseconds since pygame.init() can be retrieved by pygame.time.get_ticks(). See pygame.time module.

next_letter_time = 0
next_letter = 0

run = True
while run:
    current_time = pygame.time.get_ticks()

    # [...]

    if next_letter < len(msg):
        if current_time > next_letter_time:
            next_letter_time = current_time + 7000 # 7000 milliseconds = 7 
            finalMessage = finalMessage + msg[next_letter]
            next_letter += 1
            renderMainText = mainText.render(finalMessage, True, white)

Minimal example:

import pygame

pygame.init()
window = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()

white = (255, 255, 255)
mainText = pygame.font.SysFont(None, 50)
renderMainText = None
finalMessage = ""
msg = "test text"
next_letter_time = 0
next_letter = 0

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    current_time = pygame.time.get_ticks()
    if next_letter < len(msg):
        if current_time > next_letter_time:
            next_letter_time = current_time + 500
            finalMessage = finalMessage + msg[next_letter]
            next_letter += 1
            renderMainText = mainText.render(finalMessage, True, white)

    window.fill(0)
    if renderMainText:
        window.blit(renderMainText, (100, 100))
    pygame.display.flip()

Upvotes: 1

7u5h4r
7u5h4r

Reputation: 457

use this

@coroutine
def my_func():
    from time import sleep
    mainText = pygame.font.Font(mainFont, 40)
    finalMessage = ""
    
    for letter in msg:
        finalMessage = finalMessage + letter
        renderMainText = mainText.render(finalMessage, True, white)
        screen.blit(renderMainText, (100, 100))
        yield from sleep(0.007)
    renderMainText = mainText.render(finalMessage, True, white)

async(my_func)

yield from is according to python 3.4 for more different versions check https://docs.python.org/3/ your function will run independently without interrupting other tasks after async(my_func)

Upvotes: 0

Related Questions