Python PyGame press two buttons at the same time - python

import pygame
finish = False
while not finish:
for event in pygame.event.get():
if event.type == pygame.QUIT:
finish = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
print "A"
if event.key == pygame.K_RIGHT:
print "B"
if event.key == pygame.K_LEFT:
print "C"
Why doesn't this let me press 2 buttons at the same time and how do I make a code that does that?

The keyboard events (e.g. pygame.KEYDOWN) occure only once when a button is pressed.
Use pygame.key.get_pressed() to continuously evaluate the states of the buttons. e.g.:
finish = False
while not finish:
for event in pygame.event.get():
if event.type == pygame.QUIT:
finish = True
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
print "A"
if keys[pygame.K_RIGHT]:
print "B"
if keys[pygame.K_LEFT]:
print "C"
Or if you would rather get a list:
finish = False
while not finish:
for event in pygame.event.get():
if event.type == pygame.QUIT:
finish = True
keys = pygame.key.get_pressed()
if any(keys):
kmap = {pygame.K_UP : "A", pygame.K_RIGHT : "B", pygame.K_LEFT : "C"}
sl = [kmap[key] for key in kmap if keys[key]]
print sl

Try this:
import pygame
finish = False
while not finish:
for event in pygame.event.get():
if event.type == pygame.QUIT:
finish = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
print "A"
if event.key == pygame.K_RIGHT:
print "B"
if event.key == pygame.K_LEFT:
print "C"
In your version you're iterating over pygame.event.get() and you evaluate only the last event in the for loop (apart from the quit logic), meaning you only evaluate the last keypress. Move the code into the loop and you can evaluate all the events.
If you want to detect multiple keypresses then use pygame.key.get_pressed()
finish = False
while not finish:
for event in pygame.event.get():
if event.type == pygame.QUIT:
finish = True
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
print("C")
if keys[pygame.K_RIGHT]:
print("B")
if keys[pygame.K_UP]:
print("A")

Related

How do I check for two keyboard keys being pressed at the same time with pygame?

I'm trying to put some features into my pygame games that get executed when two keys (e.g. a + ESC) get pressed at the same time. I tried using
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_a and event.key == pygame.K_ESCAPE:
# do something
But it doesn't recognize when I hit both keys at the same time
Use pygame.key.get_pressed() to get the state of all keyboard buttons.
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and keys[pygame.K_ESCAPE]:
# [...]
Check the state of the keys when the KEYDOWN event occurs on one of the keys (a or ESC):
for event in pygame.event.get():
# [...]
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a or event.key == pygame.K_ESCAPE: # <--- or
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and keys[pygame.K_ESCAPE]:
print("a and ESC")
The same combined in a single condition:
event_list = pygame.event.get()
keys = pygame.key.get_pressed()
for event in event_list:
# [...]
if event.type == pygame.KEYDOWN and \
((event.key == pygame.K_a and keys[pygame.K_ESCAPE]) or \
(event.key == pygame.K_ESCAPE and keys[pygame.K_a])):
print("a and ESC")
Note: pygame.event.get() must be called before pygame.key.get_pressed(), since the states of the keys returned by pygame.event.get() are set when the events are evaluated.

pygame not detecting keypresses

I've been trying to get pygame to detect keypresses so later on I can move a character around on the screen. I'm new to coding so I might just be missing something simple, but I can't figure out what's wrong with the code, should I switch to pygame.key.get_pressed() or something instead? thanks in advance.
running = True
while running:
screen.fill((0,0,0))
# set background
screen.blit(background, (0,0))
player(playerX, playerY)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# detecting key presses
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_LEFT:
print("left")
if event.type == pygame.K_RIGHT:
print("right")
if event.type == pygame.K_UP:
print("up")
if event.type == pygame.KEYUP:
if event.type == pygame.K_LEFT or event.type == pygame.K_RIGHT:
print("stop")
pygame.display.update()
It is a matter of Indentation. You must evaluate the events in the event loop instead of the application loop.
If you want to determine if a certain key is pressed, the you've to verify if the event type is pygame.KEYDOWN (or pygame.KEYUP for button release) and if the .key attribute of the event is equal the key enumerator.
running = True
while running:
screen.fill((0,0,0))
# set background
screen.blit(background, (0,0))
player(playerX, playerY)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# INDENTATION
#-->|
# detecting key presses
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT: #<-- "key" instead of "type"
print("left")
if event.key == pygame.K_RIGHT: #<-- "key" instead of "type"
print("right")
if event.key == pygame.K_UP: #<-- "key" instead of "type"
print("up")
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: #<-- "key" instead of "type"
print("stop")
#-->|
# INDENTATION
However, I recommend to use pygame.key.get_pressed() instead of the KEYDOWN event.
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
pygame.key.get_pressed() returns a sequence 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.
clock = pygame.time.Clock()
velocity = 5
running = True
while running:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
playerX += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * velocity
playerY += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * velocity
screen.blit(background, (0,0))
player(playerX, playerY)
pygame.display.update()
You need to indent this part of your code to be in the for loop:
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_LEFT:
print("left")
if event.type == pygame.K_RIGHT:
print("right")
if event.type == pygame.K_UP:
print("up")
if event.type == pygame.KEYUP:
if event.type == pygame.K_LEFT or event.type == pygame.K_RIGHT:
print("stop")
pygame.display.update()
Otherwise, the event will always only be the last event from the pygame.event.get() list.
So basically, from
running = True
while running:
screen.fill((0,0,0))
# set background
screen.blit(background, (0,0))
player(playerX, playerY)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# detecting key presses
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_LEFT:
print("left")
if event.type == pygame.K_RIGHT:
print("right")
if event.type == pygame.K_UP:
print("up")
if event.type == pygame.KEYUP:
if event.type == pygame.K_LEFT or event.type == pygame.K_RIGHT:
print("stop")
pygame.display.update()
to:
running = True
while running:
screen.fill((0,0,0))
# set background
screen.blit(background, (0,0))
player(playerX, playerY)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
print("left")
if event.key == pygame.K_RIGHT:
print("right")
if event.key == pygame.K_UP:
print("up")
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
print("stop")
pygame.display.update()
(Notice the event.keys I replaced part of your event.types with.)

pygame multiple key shooting cooldown

In my game the player can shoot different coloured bullets using the WASD keys. The player can shoot bullets as fast as they can press the keys right now, which means you can mash the WASD keys and shoot a stream of bullets. I've tried creating a USEREVENT to make a cooldown for when the player can shoot, but I'm not entirely sure if I'm doing this right because the player doesn't shoot at all when I run the game.
#cooldown userevent
shot_cool = pygame.USEREVENT + 2
pygame.time.set_timer(shot_cool, 10)
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False #breaks out of the while loop
if event.type == pygame.KEYDOWN and event.type == shot_cool:
if event.key == pygame.K_w:
pygame.time.set_timer(shot_cool, 10)
player.shoot('red')
elif event.key == pygame.K_a:
pygame.time.set_timer(shot_cool, 10)
player.shoot('green')
elif event.key == pygame.K_s:
pygame.time.set_timer(shot_cool, 10)
player.shoot('white')
elif event.key == pygame.K_d:
pygame.time.set_timer(shot_cool, 10)
player.shoot('blue')
Is there any way I can make it so the player has a short cooldown until he can fire another bullet?
As I said in my comment, you fixed your problem perfectly. But since I already had it in my editor I decided I'd share a little more. Since all the keys function the same way, you can handle them in the same function block, using a dictionary. It could end up looking like this:
#cooldown userevent
EVT_SHOT_COOLDOWN = pygame.USEREVENT + 2
# shot cool down time
COOLDOWN_TIME_MS = 100
SHOT_KEYS = {
pygame.K_w:'red',
pygame.K_a:'green',
pygame.K_s:'white',
pygame.K_d:'blue',
}
running = True
shot_delay = False
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False #breaks out of the while loop
elif event_type == shot_cool:
shot_delay = False
elif event.type == pygame.KEYDOWN:
# handle shooting keys
if (event.key in SHOT_KEYS and not shot_delay):
pygame.time.set_timer(shot_cool, COOLDOWN_TIME_MS)
shot_delay = True
player.shoot(SHOT_KEYS[event.key])
# handle other keys (if any)
Thanks to the comment from RufusVS, what you said has worked perfectly. This is the working code:
shoot_cooldown = pygame.USEREVENT +2
pygame.time.set_timer(shoot_cooldown, 100)
shot_delay = False
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == shoot_cooldown:
shot_delay = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w and shot_delay == False:
pygame.time.set_timer(shoot_cooldown, 100)
shot_delay = True
player.shoot('red')
elif event.key == pygame.K_a and shot_delay == False:
pygame.time.set_timer(shoot_cooldown, 100)
shot_delay = True
player.shoot('green')
elif event.key == pygame.K_s and shot_delay == False:
pygame.time.set_timer(shoot_cooldown, 100)
shot_delay = True
player.shoot('white')
elif event.key == pygame.K_d and shot_delay == False:
pygame.time.set_timer(shoot_cooldown, 100)
shot_delay = True
player.shoot('blue')

Pygame Using Arrow Keys to "Look Around"

I am currently trying to code a series of rooms, here referred to as nodes. You start out in the first room/node (node1) facing north, and the image for north is displayed. If you press left/right/down on the arrow keys you face towards the corresponding point on the compass and the new image for that direction is displayed. If you press the up arrow key while facing north in the first node you proceed to the second node.
However when I execute this code, any key press results in me proceeding to the second node. I looked through and I feel like the use of AND statements ought to make this a non-issue but clearly I am missing something within these loops.
Thanks in advance for your help...
def node1():
node1_here = True
node1_look_north = True
node1_look_south = False
node1_look_east = False
node1_look_west = False
node1_north_image = pygame.image.load('node1north.jpg')
node1_south_image = pygame.image.load('node1south.jpg')
node1_east_image = pygame.image.load('node1east.jpg')
node1_west_image = pygame.image.load('node1west.jpg')
while node1_here:
while node1_look_north:
screen.blit(node1_north_image, (0, 0))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.KEYDOWN and pygame.K_UP:
node2()
elif event.type == pygame.KEYDOWN and pygame.K_DOWN:
node1_look_south = True and not node1_look_north
elif event.type == pygame.KEYDOWN and pygame.K_LEFT:
node1_look_east = True and not node1_look_north
elif event.type == pygame.KEYDOWN and pygame.K_RIGHT:
node1_look_west = True and not node1_look_north
while node1_look_south:
screen.blit(node1_south_image, (0, 0))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.KEYDOWN and pygame.K_DOWN:
node1_look_north = True and not node1_look_south
elif event.type == pygame.KEYDOWN and pygame.K_LEFT:
node1_look_west = True and not node1_look_south
elif event.type == pygame.KEYDOWN and pygame.K_RIGHT:
node1_look_east = True and not node1_look_south
while node1_look_east:
screen.blit(node1_east_image, (0, 0))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.KEYDOWN and pygame.K_DOWN:
node1_look_west = True and not node1_look_east
elif event.type == pygame.KEYDOWN and pygame.K_LEFT:
node1_look_south = True and not node1_look_east
elif event.type == pygame.KEYDOWN and pygame.K_RIGHT:
node1_look_north = True and not node1_look_east
while node1_look_west:
screen.blit(node1_west_image, (0, 0))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.KEYDOWN and pygame.K_DOWN:
node1_look_east = True and not node1_look_west
elif event.type == pygame.KEYDOWN and pygame.K_LEFT:
node1_look_north = True and not node1_look_west
elif event.type == pygame.KEYDOWN and pygame.K_RIGHT:
node1_look_south = True and not node1_look_west
def node2():
node2_here = True
node2_look_north = True
node2_north_image = pygame.image.load('node2north.jpg')
while node2_here:
while node2_look_north:
screen.blit(node2_north_image, (0, 0))
pygame.display.update()
Explanation:
pygame.K_UP
^this is a constant and is always true. As such,
elif event.type == pygame.KEYDOWN and pygame.K_UP:
^this will always resolve to True when you press any key, resulting in
node2()
being executed.
Solution:
elif event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
^this will check to see if the key pressed is K_UP
Hope that helps!
Reference:
Pygame key docs

PyGame wont register keydowns

I have installed pygame on my macbook and it seems to be working however it doesnt seem to be registering specific keys
For example
RunGame = True
while RunGame:
for event in pygame.event.get():
if event.type == pygame.QUIT:
RunGame = False
if event.type == pygame.K_LEFT:
Direction = 'West'
The quit code runs just fine however the left key is not registered. When i print the event the only event that is printed when i press any key is the key up and key down event so i cant do anything with specific keys. Am i using pygame wrong?
RunGame = True
while RunGame:
for event in pygame.event.get():
if event.type == pygame.QUIT:
RunGame = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
Direction = 'West'
You forgot the event.type and remember it is event.key == pygame.K_LEFT:. you had event.type == pygame.K_LEFT:

Categories

Resources