Pygame window not responding after a few seconds
Call pygame.event.get()
at the beginning of the while loop.
Pygame windows isn't responding after a few seconds of running
You missed to update the display at the end of main
by pygame.display.flip()
. Furthermore you have to control the frames per second with pygame.time.Clock.tick
in the application loop:
def main():
# [...]
while not done:
# [...]
pygame.display.flip()
clock.tick(60)
Pygame Window not Responding after few seconds
Your game is not responding, because you ask for an input
inside the application loop. input
stops the application loop and waits for input to be confirmed. If you stop the application loop, the window stops responding. Use the KEYDOWN
event to get an input in PyGame (see pygame.event
):
for event in pygame.event.get():
# [...]
if event.type == pygame.KEYDOWN:
guessed.append(event.unicode)
guessed
has to be initialized before the application loop. Don't reset it in the loop:
import pygame
pygame.init()
running = True
window_width = 600
window_height = 600
window = pygame.display.set_mode((window_width, window_height))
clock = pygame.time.Clock()
word = "something"
guessed = []
answer = ""
for c in word:
answer += c + " " if c in guessed else "_ "
print(answer)
while running:
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
guessed.append(event.unicode)
answer = ""
for c in word:
answer += c + " " if c in guessed else "_ "
print(answer)
pygame.quit()
Pygame windows not responding if the program is slow
You will need to make sure the operating system window events are being handled, or you do get that dreaded "Not Responding" thing, exactly because, well, you're not responding to events.
In general, games always have a main loop which runs all the time and pumps events, updates game logic, draws the screen and so on. (Depending on the complexity of the app and how you design things, menus might have another loop, but that's beside the point.)
Using threads
To run things concurrently in your program, you might think you can pump these events in another thread, but that's not safe to do with Pygame, so you'll instead need to do all the other things in a secondary thread:
Caution:
pygame.event.pump()
should only be called in the thread that initialized pygame.display.
Using threads will get a little hairy since there's no direct way to return a value from the thread, and knowing whether a thread is done also takes an event. Something like this (might be buggy) should do the trick.
import threading
def engine_play(finish_event, output_list):
# Here the engine searches for the best move for some time
a = 0
for _ in range(1000000000):
a += _
output_list.append(a) # could also use a queue
finish_event.set()
def run_engine_play():
finish_event = threading.Event()
output_list = []
thread = threading.Thread(target=engine_play, args=(finish_event, output_list))
thread.start()
return (finish_event, output_list)
finish_event, output_list = run_engine_play()
while True:
for event in pygame.event.get():
pass # handle events...
if finish_event.is_set():
print(output_list[0])
Using futures
You could abstract away the complexity of threads by using concurrent.futures
, but the main point stands: you have a task (a future) you'll need to wait to finish.
Using a generator
You can turn engine_play()
into a generator function to avoid using threads, but you'll need to take care that the engine function yields control back to the main loop every now and then.
def engine_play():
# Here the engine searches for the best move for some time
a = 0
for _ in range(1000000000):
a += _
if _ % 1000 == 0: # every now and then, let the loop do other things
yield None # Not done yet...
yield a
# Instantiate the generator
engine_play_gen = engine_play()
while True:
for event in pygame.event.get():
pass # handle events...
val = next(engine_play_gen) # let the engine do its thing
if val is not None:
print(val)
Pygame 'not responding' during animations
You have to handle the events in the application loop. See pygame.event.get()
respectively pygame.event.pump()
:
For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system.
while player.x != target_x and player.y != target_y:
pygame.event.pump() # <--- this is missing
if player.x < target_x:
player.x += 1
else:
player.x -= 1
if player.y < target_y:
player.y += 1
else:
player.y -= 1
draw() # updates / draws the screen
clock.tick(30)
Pygame window not responding when I try to exit the window in the middle of execution or when I spam click on the window
how do I manage it so that the program waits 14 seconds after displaying the first image, and then displays the next image?
Use pygame.time.get_ticks()
to return the number of milliseconds since pygame.init()
was called. Calculate the time that has passed since the application loop started:
def main():
clock = pygame.time.Clock()
start_time = pygame.time.get_ticks()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
current_time = pygame.time.get_ticks()
elapsed_time = current_time - start_time
if elapsed_time > 15000:
start_time = current_time
draw_window(elapsed_time)
pygame.quit()
exit()
Draw the scene depending on the elapsed time:
def draw_window(elapsed_time):
WIN.blit(BG, (0, 0))
if elapsed_time > 14000:
WIN.blit(DR_RUIN_BACK, (15, -275))
else:
WIN.blit(DR_RUIN, (15, -275))
pygame.draw.rect(WIN, BLUE, pygame.Rect(0, 450, 800, 50))
pygame.display.update()
Pygame Window Not Responding After Entering If Statement
You have to handle the events in the application loop. See pygame.event.get()
respectively pygame.event.pump()
:
For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system.
Additionally you have to get the new mouse position in every frame with pygame.mouse.get_pos()
:
while True:
pygame.event.pump()
mouse = pygame.mouse.get_pos()
# [...]
Alternatively you can use the MOUSEBUTTONDOWN
event:
ending_num = 1
while ending_num != 0:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
mouse = event.pos
if 10 < mouse[0] < 149 and 80 < mouse[1] < 130:
home_num = 0
ending_num = 0
if 10 < mouse[0] < 116 and 150 < mouse[1] < 200
home_num = 1
ending_num = 0
pygame.display.flip()
pygame.time.wait(70)
The MOUSEBUTTONDOWN
event occurs once when you click the mouse button and the MOUSEBUTTONUP
event occurs once when the mouse button is released. The pygame.event.Event()
object has two attributes that provide information about the mouse event. pos
is a tuple that stores the position that was clicked. button
stores the button that was clicked. Each mouse button is associated a value. For instance the value of the attributes is 1, 2, 3, 4, 5 for the left mouse button, middle mouse button, right mouse button, mouse wheel up respectively mouse wheel down.
Related Topics
Best Way to Convert String to Bytes in Python 3
How to Do Fuzzy Match Merge With Python Pandas
Importerror: No Module Named 'Pygame'
String Comparison in Python: Is Vs. ==
What Is Getattr() Exactly and How to Use It
About the Changing Id of an Immutable String
How to Convert Local Time String to Utc
How to Read a Text File into a String Variable and Strip Newlines
Remove Specific Characters from a String in Python
How to Do a Line Break (Line Continuation) in Python
Equivalent of Shell 'Cd' Command to Change the Working Directory
How to Split a String into a List of Characters
How to Replace Nan Values by Zeroes in a Column of a Pandas Dataframe