Reputation: 21
the code works just fine until I add the while true: also for some reason, the sleep function makes the entire code wait. however, I want only the parts after sleep() to wait
import pygame, sys
pygame.init()
from time import sleep
screen = pygame.display.set_mode((500,400))
PINK = (255,192,203)
WHITE = (255,255,255)
screen.fill(PINK)
pygame.display.update()
font = pygame.font.SysFont("comicsansms", 72)
text = font.render("loading", True, WHITE)
textrect = text.get_rect()
textrect.center = (225,40)
screen.blit(text,textrect)
while True:
pygame.event.get() sleep(1)
text = font.render(".", True, WHITE)
textrect = text.get_rect()
textrect.center = (350,40)
screen.blit(text,textrect)
sleep(0.5)
text = font.render(".", True, WHITE)
textrect = text.get_rect()
textrect.center = (370,40)
screen.blit(text,textrect)
sleep(0.5)
text = font.render(".", True, WHITE)
textrect = text.get_rect()
textrect.center = (390,40)
screen.blit(text,textrect)
sleep(0.5)
Upvotes: 2
Views: 274
Reputation: 64
I would use this for your while loop:
import pygame,sys
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill((red,green,blue)) # Max RGB value is 0-255
# then the rest of your code
# after the rest of your code add this at the end of it
pygame.display.update()
Upvotes: 0
Reputation: 11
Mr.squinty! i think the issue is in the while loop think the issue is because you are defining variables repeatedly you should define the variables out of the loop and then blit them in the loop!
Upvotes: -1
Reputation: 328
You can see that in your program, no call is being made to the event queue. In the pygame documentation for pygame.event.pump(), it says
"If you fail to make a call to the event queue for too long, the system may decide your program has locked up."
This causes the program to seem to be unresponsive. To solve this call the function pygame.event.pump() after pygame.init() so that the events are internally handeled
import pygame, sys
pygame.init()
pygame.event.pump()
from time import sleep
screen = pygame.display.set_mode((500,400))
PINK = (255,192,203)
WHITE = (255,255,255)
screen.fill(PINK)
pygame.display.update()
font = pygame.font.SysFont("comicsansms", 72)
text = font.render("loading", True, WHITE)
textrect = text.get_rect()
textrect.center = (225,40)
screen.blit(text,textrect)
while True:
sleep(1)
text = font.render(".", True, WHITE)
textrect = text.get_rect()
textrect.center = (350,40)
screen.blit(text,textrect)
sleep(0.5)
text = font.render(".", True, WHITE)
textrect = text.get_rect()
textrect.center = (370,40)
screen.blit(text,textrect)
sleep(0.5)
text = font.render(".", True, WHITE)
textrect = text.get_rect()
textrect.center = (390,40)
screen.blit(text,textrect)
sleep(0.5)
Upvotes: 0
Reputation: 14906
[...] The sleep function makes the entire code wait
Yes! It does. The entire thread anyway. PyGame uses an "event model" to work with the user-interface. Your code above "fights" against this, but while you might see the updates on-screen, essentially the application has "locked up" (is non-responsive) as far as your operating environment it concerned. Your OS thinks this because your program is not accepting events.
A PyGame application should process the events in the event-queue (even if it does nothing except exit). So instead of implementing times with time.sleep()
, it's much better to use the real-time clock provided by pygame.time.get_ticks()
. This function returns the time as the number of milliseconds since your program started. Your program needs multiple things to happen at certain times. These can be created at the beginning (time=0), with a time in the future. If the clock says this time has passed, then do the things.
One way to implement this is to create a simple structure to hold your text items, and the time they need to be drawn in the future:
### Structure to hold some text to draw
### after a certain number of seconds have passed
class TimedText:
def __init__( self, text, position, at, colour=WHITE ):
self.text = text
self.position = position,
self.at_time = at * 1000 # convert to milliseconds
self.colour = colour
Create these items before your main loop starts:
### Make some timed-text structures/objects
timed_texts = []
timed_texts.append( TimedText( "loading", (225,40), 0.0 ) )
timed_texts.append( TimedText( ".", (350,40), 0.5 ) )
timed_texts.append( TimedText( ".", (370,40), 1.0 ) )
timed_texts.append( TimedText( ".", (390,40), 1.5 ) )
Then in your main loop, look through each of the items, drawing the texts that need to be draw - but according to the clock.
# Loop through each timed-text structure
# Check if enough time has elapsed, and if-so, draw the text:
for tt in timed_texts:
if ( time_now >= tt.at_time ): # has enough time elapsed
text = font.render( tt.text, True, tt.colour )
textrect = text.get_rect()
textrect.center = tt.position
screen.blit( text, textrect )
This allows your code to process the events, and still have timed text-animation.
Reference code:
import pygame
# Window size
WINDOW_WIDTH = 500
WINDOW_HEIGHT = 400
WINDOW_SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
PINK = (255,192,203)
WHITE = (255,255,255)
### initialisation
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), WINDOW_SURFACE )
pygame.display.set_caption("Going Dotty...")
### Structure to hold some text to draw
### after a certain number of seconds have passed
class TimedText:
def __init__( self, text, position, at, colour=WHITE ):
self.text = text
self.position = position,
self.at_time = at * 1000 # convert to milliseconds
self.colour = colour
### Make some timed-text structures/objects
font = pygame.font.SysFont("comicsansms", 72)
timed_texts = []
timed_texts.append( TimedText( "loading", (225,40), 0 ) )
timed_texts.append( TimedText( ".", (350,40), 0.5 ) )
timed_texts.append( TimedText( ".", (370,40), 1.0 ) )
timed_texts.append( TimedText( ".", (390,40), 1.5 ) )
### Main Loop
clock = pygame.time.Clock()
done = False
while not done:
# Handle user-input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
elif ( event.type == pygame.MOUSEBUTTONUP ):
# On mouse-click
pass
elif ( event.type == pygame.KEYUP ):
# On key-release
#keys = pygame.key.get_pressed()
pass
# Update the window, but not more than 60fps
screen.fill( PINK )
time_now = pygame.time.get_ticks()
# Loop through each timed-text structure
# Check if enough time has elapsed, and if-so, draw the text:
for tt in timed_texts:
if ( time_now >= tt.at_time ): # has enough time elapsed
text = font.render( tt.text, True, tt.colour )
textrect = text.get_rect()
textrect.center = tt.position
screen.blit( text, textrect )
pygame.display.flip()
clock.tick_busy_loop(60)
pygame.quit()
Upvotes: 4