Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use pygame.KEYDOWN to execute something every time through a loop while the key is held down?

I made 2 functions, which would check for an event

def get_pygame_events():
  pygame_events = pygame.event.get()
  return pygame_events

and

def get_keys_pressed(self):
  keys_pressed = get_pygame_events()  #pygame.event.get(pygame.KEYDOWN)
  # print(keys_pressed)
  keys_pressed_list = []
  for event in keys_pressed:
    if event.type == pygame.KEYDOWN:
      if event.key == K_LEFT:
        keys_pressed_list.append("left")
      if event.key == K_RIGHT:
        keys_pressed_list.append("right")
      if event.key == K_UP:
        keys_pressed_list.append("up")
      if event.key == K_DOWN:
        keys_pressed_list.append("down")
      if event.key == K_a:
        keys_pressed_list.append("a")
      if  event.key == K_d:
        keys_pressed_list.append("b")
      if event.key == K_w:
        keys_pressed_list.append("w")
      if event.key == K_s:
        keys_pressed_list.append("s")
      if event.key == K_SPACE:
        keys_pressed_list.append("space")
      if event.key == K_q:
        keys_pressed_list.append("q")
      if event.key == K_e:
        keys_pressed_list.append("e")
    if event.type == pygame.MOUSEBUTTONDOWN:
      keys_pressed_list.append("click")
      return (keys_pressed_list, event.pos)
  return keys_pressed_list

I expected that if I could do something similar to:

while True:
  Variable1 = get_pygame_events()
  Variable2 = get_keys_pressed()
  if Variable2 == ["w"]:
    print("w")

(That while loop was just a summary of what I did)

Then if I held down W, "w" would be printed over and over and over again. Instead when I tried, it printed W once, and unless I pressed again, that is all that would happen.

How can I make it so by holding down the W (or any) key, it identifies the event happening, and (in this case) prints "w" every time it goes through the while loop?

like image 873
Lord_GumquestriX Avatar asked Aug 25 '14 21:08

Lord_GumquestriX


4 Answers

Use pygame.KEYDOWN and pygame.KEYUP to detect if a key is physically pressed down or released. You can activate keyboard repeat by using pygame.key.set_repeat to generate multiple pygame.KEYDOWN events when a key is held down, but that's rarely a good idea.

Instead, you can use pygame.key.get_pressed() to check if a key is currently held down:

while True:
    ...
    pressed = pygame.key.get_pressed()
    if pressed[pygame.K_w]:
       print("w is pressed")
    if pressed[pygame.K_s]:
       print("s is pressed")
like image 128
sloth Avatar answered Oct 17 '22 12:10

sloth


I would advice you to stick with the event-driven approach rather than using a polling mechanism.

You should let the key events alter some internal state to reflect a pressed key imo.

Example: You are controlling a spaceship with your keyboard. You want the propulsion rockets to fire when you press one of 'w', 's', 'a' or 'd' to make the ship accelerate in a certain direction:

  • On pygame.KEYDOWN event, set an appropriate acceleration vector for the object if event.key in [K_w, K_s, K_a, K_d].
  • On pygame.KEYUP event, set the acceleration vector to the zero vector if event.key in [K_w, K_s, K_a, K_d].

This will effectively make the object accelerate while a movement key is pressed, and stop accelerating when the key is released.

like image 29
user2015735 Avatar answered Oct 17 '22 10:10

user2015735


event.key == chr('a') 

event.key returns the ascii of the key

like image 4
xwang Avatar answered Oct 17 '22 12:10

xwang


Use pygame.key.set_repeat().

set_repeat(delay, interval) -> None.

When the keyboard repeat is enabled, keys that are held down will generate multiple pygame.KEYDOWN events. The delay is the number of milliseconds before the first repeated pygame.KEYDOWN will be sent. After that another pygame.KEYDOWN will be sent every interval milliseconds. If no arguments are passed the key repeat is disabled.

like image 1
Luke Borowy Avatar answered Oct 17 '22 10:10

Luke Borowy