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

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)

Related

How can I execute a function when a specific key is pressed and released in python [duplicate]

This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
How can I make a sprite move when key is held down
(6 answers)
Closed 12 months ago.
I'm trying to write a 2D game in Python and I'm trying to call a function when I press and release Spacebar from my keyboard. If I'm using the function "is_pressed()" from keyboard it will be continuously called and glitch my program. Can you help, please?
You have to use the keyboard events instead. pygame.key.get_pressed() returns a list with the state of each key. If a key is held down, the state for the key is True, otherwise False. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement. The keyboard events (see pygame.event module) occur only once when the state of a key changes. The KEYDOWN event occurs once every time a key is pressed. KEYUP occurs once every time a key is released. Use the keyboard events for a single action or a step-by-step movement.
e.g.:
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
# do something
# [...]
if event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
# do something
# [...]

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()

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

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()

Pygame.display.update() disappearing [duplicate]

This question already has answers here:
Trying to display a png file in pygame using pygame.display.update, and it shows for less than a second then disappears.
(2 answers)
Closed 7 years ago.
We have recently moved our school lab to Mac, and when I run some code to display an image from a file, the display appears then disappears immediately. I am using the 3.4 interpreter in Pycharm and Pygame version 1.9.2. Can someone please help?
Here is my code:
# displays a hard-coded filename in a window
import pygame
pygame.init()
picture = pygame.image.load("cards/S01.png")
pygame.display.set_mode(picture.get_size())
main_surface = pygame.display.get_surface()
main_surface.blit(picture, (0, 0))
pygame.display.update()
If the code you posted is the complete code, then that is the reason why its exiting immediately, because immediately after calling pygame.display.update() , the program exits. I do not think this should have been working before.
One thing you can do for this , add a loop to run till the user presses close, after your code -
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
Put a
time.sleep(10)
after pygame.display.update() see if it stays up longer.

Pygame hold key down causes an infinite loop [duplicate]

This question already has answers here:
How to efficiently hold a key in Pygame?
(7 answers)
Closed 8 years ago.
I am trying to write a Pong game in which I can move the paddle using the up and down arrows. I created a Paddle object that updates by a given amount (passed as the parameter "num" in the code below) each time the up key is pressed. What I want to do is allow the user to hold the up button down which would cause the paddle to continuously move in the up direction. I tried writing this event handling in a while loop, but I got stuck in an infinite loop. Here is the code below:
for event in PE.get():
if event.type == PG.KEYDOWN:
keystate = PG.key.get_pressed()
if event.key == PG.K_ESCAPE:
done = True
while keystate[PL.K_UP]:
rightPaddle.update(-20)
if event.type == PG.QUIT:
done = True
Below is the code for the Paddle object:
class Paddle(object):
def __init__(self, x, y):
self.topleftx = x
self.toplefty = y
self.width = 15
self.height = 100
def draw(self, surface):
rect = PR.Rect(self.topleftx, self.toplefty, \
self.width, self.height)
surface.fill(WHITE, rect)
def update(self, num):
self.toplefty += num
I checked other stackoverflow questions on this topic, which is how I found the PG.key.getPressed() method, but other answers suggest using "sprites" which I'm not sure how to use. Could anyone offer some advice on how to go about performing this task?
The problem with the while loop is that it's evaluating the one keydown event. That event will always be whatever it starts as, and there's no chance for it to change within the event handling code. What you want to catch is the PG.KEYUP event that follows it. So you'll have something (logically) like
if event.type == PG.KEYDOWN and keystate[PL.K_UP]:
key_up_pressed = True
elif event.type == PG.KEYUP and keystate[PL.K_UP]:
key_up_pressed = False
Obviously, you can factor that better, but the key_up_pressed state will get evaluated in your main loop once every so often (frame, millisecond, whatever), and move the paddle.
In this code:
while keystate[PL.K_UP]:
rightPaddle.update(-20)
… there is nothing that can change keystate. So, if keystate[PL.K_UP] is true once, it will be true forever. Hence the infinite loop.
You could fetch the current key information from pygame each time through the loop, which would at least make it not infinite—but it would still mean your entire program blocks up until the user releases the key.
Without knowing whether you intended to write a frame-rate-driven game or an event-loop-driven game, I can't tell you exactly how to fix it.
But either way, the key point is that you don't want to move over and over as long as the key is held down, you want to move at a certain speed, processing other events in between, as long as the key is held down. Either way, you'll use the KEYDOWN and KEYUP events to set some kind of flag that tells you to move the paddle. Then, once per frame, or using a timer event, or in some other way, you will use the current flag value to move the paddle.

Categories

Resources