How to wait some time in pygame?
For animation / cooldowns, etc: If you want to 'wait', but still have code running you use: pygame.time.get_ticks
class Unit():
def __init__(self):
self.last = pygame.time.get_ticks()
self.cooldown = 300
def fire(self):
# fire gun, only if cooldown has been 0.3 seconds since last
now = pygame.time.get_ticks()
if now - self.last >= self.cooldown:
self.last = now
spawn_bullet()
Delay inside a while loop (Python/Pygame)
Since you are using pygame
you should use
pygame.time.wait(5000)
instead of
time.sleep(5)
Note that wait requires milliseconds instead of seconds!
Why does my game freeze when using pygame.time.wait or pygame.time.delay?
You can not wait inside the application loop. pygame.time.wait
halts the loop and makes the application irresponsible.
Use pygame.time.get_ticks()
to return the number of milliseconds since pygame.init()
was called. Calculate the point in time when the block needs to be move. When the time is reached, move the block and calculate the time when the block has to be moved again:
next_block_move_time = 0
while notDone:
# [...]
# sprite_list.update() <--- DELETE
current_time = pygame.time.get_ticks()
if current_time > next_block_move_time:
# set next move time
next_block_move_time = current_time + 500 # 500 milliseconds = 0.5 seconds
# move blocks
block_list .update()
Using pygame.time.wait() between display updates
You need to seperate your algorithm from the drawing aspect of your code.
A simple way to update your code would be to use a coroutine that, at every step of your recursive hanoi
function, gives the control back to the main loop, which in turn draws the screen, and gives control back to the hanoi
coroutine every second.
Here's a simplified example that just counts down:
#-*- coding-utf8 -*-
import pygame
import pygame.freetype
pygame.init()
screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
font = pygame.freetype.SysFont(None, 30)
def hanoi(num):
# We calculated something and want to print it
# So we give control back to the main loop
yield num
# We go to the next step of the recursive algorithm
yield from hanoi(num-1) #
steps = hanoi(1000)
ticks = None
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
exit()
# step every second only
if not ticks or pygame.time.get_ticks() - ticks >= 1000:
ticks = pygame.time.get_ticks()
screen.fill((200, 200, 200))
# the value from the next step of the coroutine
value = str(next(steps))
# render stuff onto the screen
font.render_to(screen, (100, 100), value)
pygame.display.flip()
clock.tick(60)
In your code, you should replace
# updates and waits
printBackground()
printPieces(positions)
pg.time.wait(1000)
with yield positions
to give control back to the main loop and
hanoi(n-1, aux, destination, origin)
with
yield from hanoi(n-1, aux, destination, origin)
to keep the coroutine running and call
...
screen.fill((200, 200, 200))
positions = next(steps)
printBackground()
printPieces(positions)
...
inside the if
in the main loop.
(If the algorithm finish, it will raise a StopIterationException
which you probably want to catch).
Pygame and pygame.time.wait() function is working in a bizarre way
In order to update what is shown in the pygame window, you must call pygame.display.update(), like so:
import pygame
BlockList=[]
pygame.init()
block_side_length=30
black = 0,0,0
GameArea_start_x=5
GameArea_start_y=5
GameArea_width=300
GameArea_height=270
gameDisplay = pygame.display.set_mode((400,300))
pygame.display.set_caption("Tetris")
gameDisplay.fill((0,100,100))
GameArea = pygame.draw.rect(gameDisplay,black,[GameArea_start_x,GameArea_start_y,GameArea_width,GameArea_height])
lowest_block_y =GameArea_start_y+GameArea_height-block_side_length
pygame.display.update()
pygame.time.wait(2000)
gameDisplay.fill((0,100,100))
pygame.draw.rect(gameDisplay,(0,250,0),[50,50,40,90])
pygame.display.update()
pygame.time.wait(2000)
gameDisplay.fill((0,100,100))
pygame.display.update()
Note that your approach of calling pygame.time.wait()
for long periods of time will cause the window to freeze and become unresponsive while waiting. Some better approaches are described in this stackoverflow question.
Time delay in python/pygame without disrupting the game?
You could add in some logic in that will only advance a
if 4 seconds have passed.
To do this you can use the time module and get a starting point last_time_ms
Every time we loop, we find the new current time and find the difference between this time and last_time_ms
. If it is greater than 4000 ms, increment a
.
I used milliseconds because I find its usually more convenient than seconds.
import time
a=0
last_time_ms = int(round(time.time() * 1000))
while True:
diff_time_ms = int(round(time.time() * 1000)) - last_time_ms
if(diff_time_ms >= 4000):
a += 1
last_time_ms = int(round(time.time() * 1000))
for event in pygame.event.get():
if event.type==QUIT:
pygame.quit()
sys.exit()
Intro.stop()
TWD.stop()
if a <= 3:
screen.blit(pygame.image.load(images[a]).convert(),(0,0))
Intro.play()
if a == 4:
Intro.stop()
TWD.play()
pygame.display.update()
Related Topics
What Is the Python Equivalent of Static Variables Inside a Function
Python Function Global Variables
How to Pass a String into Subprocess.Popen (Using the Stdin Argument)
Is Explicitly Closing Files Important
Is There a Simple, Elegant Way to Define Singletons
How to Get Indices of N Maximum Values in a Numpy Array
Python Pandas Error Tokenizing Data
How to Update a Plot in Matplotlib
How to Find All Matches to a Regular Expression in Python
Why Can't Python'S Raw String Literals End With a Single Backslash
How to Merge Dictionaries of Dictionaries
Process Escape Sequences in a String in Python
Difference Between Images in 'P' and 'L' Mode in Pil
Adding a New Pandas Column With Mapped Value from a Dictionary