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.)
Related
while True:
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_SPACE:
print("Pressed Space")
else:
if event.key == pygame.K_w:
print("Pressed w")
screen.blit(background, background_rect)
pygame.display.update()
I have a Mac and for some reason its not registering any of my keyboard inputs except for left shift. How can I fix this? (Pygame)
I believe your error is because of incorrect indentation. The event checking in the for event in pygame.event.get() loop needs to be inside the loop to run on all events.
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# moved this in one level --->
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
print("Pressed Space")
elif event.key == pygame.K_w: # no need for an "else" then an "if"
print("Pressed w")
screen.blit(background, background_rect)
pygame.display.update()
I'm trying to write something simple in pygame, but this is something I don't understand.
I'm trying to add moving but it's not continuous. I press and hold the key but the key only goes through 1 x_change
import pygame, sys
from pygame.locals import *
pygame.init()
gDis=pygame.display.set_mode((400,300))
Black=(0,0,0)
White=(255,255,255)
Red=(255,0,0)
Blue=(0,0,255)
Silver=(192,192,192)
clock=pygame.time.Clock()
x=195
y=270
wid=20
hght=20
speed=5
x_change=0
y_change=0
left=False
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == K_LEFT:
x_change-=5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change=0
x+=x_change
gDis.fill(Black)
pygame.draw.rect(gDis, Silver, (x, y, wid, hght))
clock.tick(60)
pygame.display.update()
It is a matter of Indentation. You must move and draw the player in the application loop instead of the event loop:
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == K_LEFT:
x_change = -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
# INDENTATION
#<--|
x += x_change
gDis.fill(Black)
pygame.draw.rect(gDis, Silver, (x, y, wid, hght))
pygame.display.update()
clock.tick(60)
#enable pygame mode
import pygame
pygame.init()
#create screen
screen = pygame.display.set_mode((900,600))
#Title + Logo
pygame.display.set_caption("Space Invader")
icon = pygame.image.load("chicken.png")
pygame.display.set_icon(icon)
#Player icon
player_icon = pygame.image.load("spaceship.png")
playerX = 400
playerY = 500
def player(x, y):
screen.blit(player_icon, (x, y))
#game loop
running = True
while running:
# backround colour RGB
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#If key pressed check wether its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
print("key left pressed")
if event.key == pygame.K_RIGHT:
print("key right pressed")
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
print("key stroke has benn released")
#Player change in coordinates
playerX += 0
playerY += 0
player(playerX, playerY)
pygame.display.update()
I have been learning about pygame and game programing using python during this quarantine. I have been doing this by watching a tutorial on youtube. Please don't downgrade me I have tried harder to make my question better last time it was my first question and got 2 downgrades. Thankyou for your time.
It s a matter of Indentation. In your code the pygame.KEYDOWN event is only evaluated in case of event.type == pygame.QUIT. "Move" the pygame.KEYDOWN event handling:
running = True
while running:
# backround colour RGB
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# <--| INDENTATION
#If key pressed check wether its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
print("key left pressed")
if event.key == pygame.K_RIGHT:
print("key right pressed")
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
print("key stroke has benn released")
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
I have a python program using pygame, but when I run it it gives me a syntax error on the pygame.display.update line. I'm not sure what is causing it. Any help is appreciated!
import pygame, sys
import time
from pygame.locals import *
pygame.init()
area = pygame.display.set_mode((400, 300))
red=(255, 0, 0)
black=(0, 0, 0)
fps = 30
clock=pygame.time.Clock()
x=100
y=100
a=0
b=0
pygame.display.set_caption('Reddy For School')
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
b=-10
if event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN:
b=10
if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
a=-10
if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
a=10
if event.type == pygame.KEYUP and event.key == pygame.K_UP:
b=0
if event.type == pygame.KEYUP and event.key == pygame.K_DOWN:
b=0
if event.type == pygame.KEYUP and event.key == pygame.K_LEFT:
a=0
if event.type == pygame.KEYUP and event.key == pygame.K_RIGHT:
a=0
x+=a
y+=b
pygame.draw.rect(area, red, (x, y, 100, 100)
python.display.update()
area.fill(black)
clock.tick(fps)
As per the comments, you're missing a parentheses.
I'm not sure what the python.display.update() was trying to achieve, but I guess flush the display-updates to the screen. I substituted this with pygame.display.flip().
There's a couple of painting issues too - the code is drawing a red square, but then filling the screen with black. These needed to be re-ordered.
Also your main event-loop was not exiting cleanly (under Linux, I could not close the window with the titlebar (x) ). And finally, you had not parameterised the window width and height. Soon you will need to calculate something that relies on the window width (e.g.: centering something), so it is best to start with these in a parameter instead of having "400" & "300" all over the code.
import pygame, sys
import time
from pygame.locals import *
pygame.init()
window_width = 400
window_height = 300
area = pygame.display.set_mode((window_width, window_height))
red=(255, 0, 0)
black=(0, 0, 0)
fps = 30
clock=pygame.time.Clock()
x=100
y=100
a=0
b=0
pygame.display.set_caption('Reddy For School')
running = True
while running:
for event in pygame.event.get():
# check for closing the window
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
b=-10
if event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN:
b=10
if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
a=-10
if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
a=10
if event.type == pygame.KEYUP and event.key == pygame.K_UP:
b=0
if event.type == pygame.KEYUP and event.key == pygame.K_DOWN:
b=0
if event.type == pygame.KEYUP and event.key == pygame.K_LEFT:
a=0
if event.type == pygame.KEYUP and event.key == pygame.K_RIGHT:
a=0
x+=a
y+=b
area.fill(black)
pygame.draw.rect(area, red, (x, y, 100, 100) )
clock.tick(fps)
pygame.display.flip() #quicker process to draw things
pygame.quit()