How should I properly program an immediate exit procedure in pygame? [duplicate] - python

This question already has answers here:
How to wait some time in pygame?
(3 answers)
Move an object every few seconds in Pygame
(2 answers)
Closed 1 year ago.
I have this piece of code in the end of my main function in a python pygame script. This seems to be the correct way to handle an exit with a simple keypush.
running = True
while running == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
break
elif event.type == pygame.KEYDOWN:
running = False
break
if running == False:
break
draw(screen, background)
pygame.quit() # quits pygame
sys.exit()
However in this draw function I also have the following line right before the closing accolade:
pygame.time.delay(randint(2,5) * 1000)
This line of code makes the game wait anywhere from 2 till 5 seconds. Apparently this delay code creates an extra delay of about 3 loops in detecting the key pushes.
My question is: how do I properly execute an immediate exit with a key push without waiting for the delay?
Edit: Solution (credit to HÃ¥ken Lid)
animate_event = pygame.USEREVENT
pygame.time.set_timer(animate_event, 1000)
while True:
if pygame.event.get(pygame.QUIT): break
if pygame.event.get(pygame.KEYDOWN): break
for event in pygame.event.get():
if event.type == animate_event:
animate(screen, background)
# reset event
pygame.time.set_timer(animate_event, randint(2,5)*1000)
pygame.quit()
sys.exit()

Related

Pygame window does not close properly when clock.tick in the loop

I'm working on a project and when I add the clock.tick to my main game loop, my pygame window doesnt close.
def game_loop():
"""The main game loop that runs as the game runs. Returns when the pygame window is closed."""
global running
global timer
while running:
while timer > screen.fixed_fps:
fixed_update()
timer -= screen.fixed_fps
update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
return
screen.clock.tick(screen.fps)
timer += delta_time()
pygame.quit()
return
When I click the X, the screen freezes until I let go, but unless I click the X in a very specific time frame( I usually need to click it 20 times to close) it doesnt work.
This is likely because of the way you are handling the QUIT event in your event loop. The pygame.event.get() function returns all of the events that have occurred since the last time it was called, so if there is a delay in your loop, the QUIT event may not be handled until multiple events have accumulated. To fix this, you should move the QUIT event handling code to the top of your event loop so that it is handled as soon as the event occurs. Also you could try to add pygame.display.update() after the event handling to make sure it is updated.
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
return
while timer > screen.fixed_fps:
fixed_update()
timer -= screen.fixed_fps
update()
screen.clock.tick(screen.fps)
timer += delta_time()

Why do key presses sometimes work and sometimes not? [duplicate]

This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?
(1 answer)
Closed last month.
I have some code to check if "q" is pressed and then I make an instance of a class. The problem is that sometimes it recognizes a press of the button and sometimes it doesn't. For example if I press "q" 10 times, sometimes it will recognize the press 3 times, sometimes 6 times, sometimes 7 times. So how can I fix it so it will recognize the press every single time? Some people said that it's probably because I call pygame.event.get() multiple times. Because of that I have tried getting events once in the whole script, but it's still the same result.
Code:
pygame.init()
fpsClock = pygame.time.Clock()
screen = pygame.display.set_mode((1920, 1080)
while True:
#Input
self.events = self.pygame.event.get()
for event in self.events:
if event.type == self.QUIT:
self.pygame.quit()
self.sys.exit()
if event.type == self.pygame.KEYDOWN:
if event.key == self.pygame.K_q:
#makes an instance
pygame.display.flip()
fpsClock.tick(60)

Quit from program in pygame [duplicate]

This question already has answers here:
Pygame unresponsive display
(1 answer)
Pygame window not responding after a few seconds
(3 answers)
Closed 2 years ago.
I am trying to understand why my program is loosing respond when I trying exit from game. I make some test and here is code:
import pygame
import time
pygame.init()
run=True
pygame.display.set_caption("test")
win=pygame.display.set_mode((200,200))
while run==True:
pygame.time.delay(16)
keys=pygame.key.get_pressed()
#for event in pygame.event.get():
#if event.type == pygame.QUIT:
#run=False
win.fill((125,125,125))
if keys[pygame.K_q]:
run=False
pygame.display.update()
pygame.quit()
If execute this code - windows can't properly exit from program when user pressed key "q".
If remove comments symbols # form 14,15,16 strings, all will work properly. Hitting "q" key will exit from program normally.
Only one question - why???
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.
If you don't handle the events, pygame.key.get_pressed() will stop working. The states of the keys returned by pygame.key.get_pressed() are evaluated internally when the events are handled.
At least you've to call pygame.event.pump():
while run==True:
pygame.time.delay(16)
pygame.event.pump()
keys=pygame.key.get_pressed()
if keys[pygame.K_q]:
run=False
win.fill((125,125,125))
pygame.display.update()

Pygame window immediately opens and closes

Originally after I did some searching here, I found a question with the exact same problem I had:
Pygame window not responding after a few seconds . I reviewed all the answers and tried them, but none of them worked. I tried using for loops to loop through every single event;
run = True
while run:
for event in pygame.event.get():
if event == pygame.QUIT()
run = False
But the window still closed. I also tried:
run = True
while run:
event = pygame.event.get()
if event == pygame.QUIT():
run = False
Which had the same results as the one above.
Can anyone help?
Edit: I use PyCharm and MacOS Catalina.
pygame.QUIT is a constante, but pygame.QUIT() is a call statement. Remove the braces. Anyway, the condition won't work, because you have to compare the type attribute of the event to the event type constant (see pygame.event). Furthermore the : is missing at the end of the if-statement.
if event == pygame.QUIT()
if event.type == pygame.QUIT:
Furthermore the Indentation is not correct:
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False

Pygame not exiting on keypress

I've been following along with a bouncing ball example just to get my chops warmed up with pygame: every time I test my code I have to kill the game window by causing it to freeze, though in my code (taken directly from the pygame website) I state that the game should exit if the Escape key is pressed or the X button on the screen. I get an error
running == False
NameError: name 'running' is not defined
my code is
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running == False
if event.type ==pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
running == False
can I define "running?" such that the game doesn't simply freeze when I try to quit.
First off, you should define running to True (running = True) above your while loop. Secondly, you should be checking that value somewhere; easiest is to change while 1 to while running Third, == is checking for equality, = is setting a value. You want to check event.type to be pygame.QUIT or KEYDOWN, so those == are correct, but then you want to set running to False, which is running = False. Doing running == False as a statement is not effective.

Categories

Resources