Reputation: 55
I have a function that detects key presses but, when i use the function and detect 'a' it detects but if i detect 'd' it doesnt detect it, but if i put the function that detects the key 'd' before the function that detects the key 'a' it detects 'd', why so?
here is my code:
keys = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','space','1','2','3','4','5','6','7','8','9','0']
pygame_keys = [pygame.K_a,pygame.K_b,pygame.K_c,pygame.K_d,pygame.K_e,pygame.K_f,pygame.K_g,pygame.K_h,pygame.K_i,pygame.K_j,pygame.K_k,pygame.K_l,pygame.K_m,pygame.K_n,pygame.K_o,pygame.K_p,pygame.K_q,pygame.K_r,pygame.K_s,pygame.K_t,pygame.K_u,pygame.K_v,pygame.K_w,pygame.K_x,pygame.K_y,pygame.K_z,pygame.K_SPACE,pygame.K_1,pygame.K_2,pygame.K_3,pygame.K_4,pygame.K_5,pygame.K_6,pygame.K_7,pygame.K_8,pygame.K_9,pygame.K_0]
def key_pressed(key_press,one_click =False):
global key_function_run
if one_click:
key_function_run = True
if not one_click:
if kb.is_pressed(key_press):
return True
if one_click:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
for i in range(len(keys)):
if event.type == pygame.KEYDOWN:
if key_press == keys[i]:
if event.key == pygame_keys[i]:
print(i)
return True
pass
And here is how i am using the function:
if x == 205:
player_lane = 2
if x == 60:
player_lane = 1
if x == 347:
player_lane = 3
#player movement
if peasy.key_pressed('a',True) and player_lane == 2:
x = 60
if peasy.key_pressed('a',True) and player_lane == 3:
x = 205
if peasy.key_pressed('d',True) and player_lane == 2:
x = 347
if peasy.key_pressed('d',True) and player_lane == 1:
x = 205
Upvotes: 0
Views: 158
Reputation: 210909
Make a dictionary from your lists:
key_dict = dict(zip(keys, pygame_keys))
And use pygame.key.get_pressed
:
def key_hold(keys, key):
return keys[key_dict[key]]
keys = pygame.key.get_pressed()
is_a = key_hold(keys, 'a')
is_d = key_hold(keys, 'd')
If you want to use the KEYDOWN
event, you have to be aware that pygame.event.get()
get all the messages and remove them from the queue. See the documentation:
This will get all the messages and remove them from the queue. [...]
So you can call pygame.event.get
only once per frame. Also see Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?. However you can use unicode
property of the KEYDOWN
event:
def key_down_event(event_list, c):
return any(e for e in event_list if e.type == pygame.KEYDOWN and e.unicode == c)
event_list = pygame.event.get()
is_a = key_down_event(event_list, 'a')
is_d = key_down_event(event_list, 'd')
If you want a function that detects both whether a key is held down or has been pressed, you need to count the frames of how long a key is pressed, for each key. Return True
if the count for a key is 1 when you want to determine if the key was just pressed:
import pygame
key_count = {}
def key_pressed(keys, key, one_click):
pressed = keys[key]
key_count[key] = (key_count.get(key, 0) + 1) if pressed else 0
return key_count[key] == 1 if one_click else pressed
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
a_once = key_pressed(keys, pygame.K_a, True)
d_hold = key_pressed(keys, pygame.K_d, False)
if a_once:
print(f'key event: {pygame.key.name(pygame.K_a)}')
if d_hold:
print(f'key pressed: {pygame.key.name(pygame.K_d)}')
pygame.display.flip()
pygame.quit()
exit()
Upvotes: 1
Reputation: 23
You shouldn't need to make a custom function for input handling, you can use something like this:
running = True
def main():
# Your normal game loop
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# Gets a list of the currently pressed keys,
# this is updated because we put it in the while loop
kbd = pygame.key.get_pressed()
if kbd[pygame.K_a]:
print("I just pressed the A button!") # You can run here whatever ya want
Edit: I realized OP wanted to use pygame.KEYDOWN
instead of pygame.key.get_pressed()
, so in that case, you can use something like this
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
print("Pressed D!")
Hope I helped. If you have any questions, just leave a comment/reply/whatever!
Upvotes: 0