How to get keyboard input in pygame?
You can get the events from pygame and then watch out for the KEYDOWN
event, instead of looking at the keys returned by get_pressed()
(which gives you keys that are currently pressed down, whereas the KEYDOWN
event shows you which keys were pressed down on that frame).
What's happening with your code right now is that if your game is rendering at 30fps, and you hold down the left arrow key for half a second, you're updating the location 15 times.
events = pygame.event.get()for event in events: if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: location -= 1 if event.key == pygame.K_RIGHT: location += 1
To support continuous movement while a key is being held down, you would have to establish some sort of limitation, either based on a forced maximum frame rate of the game loop or by a counter which only allows you to move every so many ticks of the loop.
move_ticker = 0keys=pygame.key.get_pressed()if keys[K_LEFT]: if move_ticker == 0: move_ticker = 10 location -= 1 if location == -1: location = 0if keys[K_RIGHT]: if move_ticker == 0: move_ticker = 10 location+=1 if location == 5: location = 4
Then somewhere during the game loop you would do something like this:
if move_ticker > 0: move_ticker -= 1
This would only let you move once every 10 frames (so if you move, the ticker gets set to 10, and after 10 frames it will allow you to move again)
import pygamepygame.init()pygame.display.set_mode()while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit(); #sys.exit() if sys is imported if event.type == pygame.KEYDOWN: if event.key == pygame.K_0: print("Hey, you pressed the key, '0'!") if event.key == pygame.K_1: print("Doing whatever")
In note that K_0 and K_1 aren't the only keys, to see all of them, see pygame documentation, otherwise, hit tab
after typing in
pygame.
(note the . after pygame) into an idle program. Note that the K must be capital. Also note that if you don't give pygame a display size (pass no args), then it will auto-use the size of the computer screen/monitor. Happy coding!
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:
while True: keys = pygame.key.get_pressed() x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * speed y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * speed
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 movement:
while True: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: x -= speed if event.key == pygame.K_RIGHT: x += speed if event.key == pygame.K_UP: y -= speed if event.key == pygame.K_DOWN: y += speed
See also Key and Keyboard event
Minimal example of continuous movement: replit.com/@Rabbid76/PyGame-ContinuousMovement
import pygamepygame.init()window = pygame.display.set_mode((300, 300))clock = pygame.time.Clock()rect = pygame.Rect(0, 0, 20, 20)rect.center = window.get_rect().centervel = 5run = Truewhile run: clock.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False if event.type == pygame.KEYDOWN: print(pygame.key.name(event.key)) keys = pygame.key.get_pressed() rect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel rect.y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel rect.centerx = rect.centerx % window.get_width() rect.centery = rect.centery % window.get_height() window.fill(0) pygame.draw.rect(window, (255, 0, 0), rect) pygame.display.flip()pygame.quit()exit()
Minimal example for a single action: replit.com/@Rabbid76/PyGame-ShootBullet
import pygamepygame.init()window = pygame.display.set_mode((500, 200))clock = pygame.time.Clock()tank_surf = pygame.Surface((60, 40), pygame.SRCALPHA)pygame.draw.rect(tank_surf, (0, 96, 0), (0, 00, 50, 40))pygame.draw.rect(tank_surf, (0, 128, 0), (10, 10, 30, 20))pygame.draw.rect(tank_surf, (32, 32, 96), (20, 16, 40, 8))tank_rect = tank_surf.get_rect(midleft = (20, window.get_height() // 2))bullet_surf = pygame.Surface((10, 10), pygame.SRCALPHA)pygame.draw.circle(bullet_surf, (64, 64, 62), bullet_surf.get_rect().center, bullet_surf.get_width() // 2)bullet_list = []run = Truewhile run: clock.tick(60) current_time = pygame.time.get_ticks() for event in pygame.event.get(): if event.type == pygame.QUIT: run = False if event.type == pygame.KEYDOWN: bullet_list.insert(0, tank_rect.midright) for i, bullet_pos in enumerate(bullet_list): bullet_list[i] = bullet_pos[0] + 5, bullet_pos[1] if bullet_surf.get_rect(center = bullet_pos).left > window.get_width(): del bullet_list[i:] break window.fill((224, 192, 160)) window.blit(tank_surf, tank_rect) for bullet_pos in bullet_list: window.blit(bullet_surf, bullet_surf.get_rect(center = bullet_pos)) pygame.display.flip()pygame.quit()exit()