I am coding with python on my raspberry pi. Python isn't my best language so bear with me.
I need a simple code that responds to key strokes on my keyboard. I'd doing this so I can set the Pulse Width Modulation, but I don't need that code, I already have it. My main concern is I am struggling to understand the pygame functionality required for my task.
I would like to be able to type a key, such as "up arrow" ↑ and have the program output "up pressed" for every millisecond the up arrow is pressed.
The pseudo-code would look like:
double x = 1
while x == 1:
if input.key == K_UP:
print("Up Arrow Pressed")
if input.key == K_q
x = 2
wait 1ms
pygame.quit()
Again I have no clue what to import or call due to not knowing the syntax.
Here's some code that will check if the ↑ key is pressed:
import pygame
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode([320,240])
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
print("Up Arrow Pressed")
elif keys[pygame.K_q]:
done = True
clock.tick(1000)
pygame.quit()
Note that clock.tick(1000) will limit the code to one-thousand frames per second, so won't exactly equate to your desired 1 millisecond delay. On my PC I only see a frame rate of around six-hundred.
Perhaps you should be looking at the key down and key up events and toggle your output then?
import pygame
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode([320,240])
done = False
output = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
output = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
output = False
elif event.key == pygame.K_q:
done = True
pygame.display.set_caption(f"Output Status {output}")
clock.tick(60)
pygame.quit()
If you run this, you'll see the title of the window change whilst the ↑ key is pressed.
Related
This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
How can I make a sprite move when key is held down
(6 answers)
Closed 1 year ago.
I am a newbie to pygame so when I type the below code in, it shows that there is no such thing as a 'type' attribute for the event object. Can you please tell me what's the error.
# Importing libraries and other stuff
import pygame
from pygame.locals import *
# defining the funtion for drawing the block
def draw_block():
surface.fill((232,127,7))
surface.blit(block,(block_x,block_y))
pygame.display.flip()
if __name__ == "__main__":
pygame.init()
surface = pygame.display.set_mode((500,500))
surface.fill((232,127,7))
block = pygame.image.load("block_better_3.jpg").convert()
block_x = 100
block_y = 100
surface.blit(block,(block_x,block_y))
pygame.display.flip()
# Making the window run until user input
running = True
while running:
for event in pygame.event.get():
if event.type == K_ESCAPE:
running = False
elif event.type == QUIT:
running = False
elif event.key == K_UP:
block_y -= 10
elif event.key == K_DOWN:
block_y += 10
elif event.key == K_LEFT:
block_x -= 10
elif event.key == K_RIGHT:
block_x +=10
If you want to know when a key is pressed, you need to verify that the event type (event.type) is KEYDOWN and the key attribute of the event object (event.key) is the specific key (K_ESCAPE, K_UP, ...):
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
elif event.key == K_UP:
block_y -= 10
elif event.key == K_DOWN:
block_y += 10
elif event.key == K_LEFT:
block_x -= 10
elif event.key == K_RIGHT:
block_x += 10
See also pygame.event module and pygame.key module.
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.
If you want to achieve a continuously movement, you have to use pygame.key.get_pressed(). 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:
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
keys = pygame.key.get_pressed()
if keys[K_UP]:
block_y -= 1
if keys[K_DOWN]:
block_y += 1
if keys[K_LEFT]:
block_x -= 1
if keys[K_RIGHT]:
block_x += 1
Further more you need to redraw the scene in every frame:
# Importing libraries and other stuff
import pygame
from pygame.locals import *
# defining the funtion for drawing the block
def draw_block():
surface.fill((232, 127, 7))
surface.blit(block,(block_x, block_y))
pygame.display.flip()
if __name__ == "__main__":
pygame.init()
surface = pygame.display.set_mode((500,500))
clock = pygame.time.Clock()
block = pygame.image.load("block_better_3.jpg").convert()
block_x = 100
block_y = 100
# application loop
running = True
while running:
# limit the frames per second
clock.tick(100)
# handle the events
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
# update the game states and positions of objects
keys = pygame.key.get_pressed()
block_x += (keys[K_RIGHT] - keys[K_LEFT]) * 2
block_y += (keys[K_DOWN] - keys[K_UP]) * 2
# clear the display; draw the scene; update the display
draw_block()
pygame.quit()
The typical PyGame application loop has to:
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
I want to close the game after was pressed the esc button. how can I do? And where should I place it?
I also found some problems that I can't solve, so if you solve them for me I would be happy
This is the code:
#Import Libraries
import pygame
import random
#PyGame Initialization
pygame.init()
#Images Variables
background = pygame.image.load('images/sfondo.png')
bird = pygame.image.load('images/uccello.png')
base = pygame.image.load('images/base.png')
gameover = pygame.image.load('images/gameover.png')
tube1 = pygame.image.load('images/tubo.png')
tube2 = pygame.transform.flip(tube1, False, True)
#Display Create
display = pygame.display.set_mode((288,512))
FPS = 60
#Define Functions
def draw_object():
display.blit(background, (0,0))
display.blit(bird, (birdx, birdy))
def display_update():
pygame.display.update()
pygame.time.Clock().tick(FPS)
def animations():
global birdx, birdy, bird_vely
birdx, birdy = 60, 150
bird_vely = 0
#Move Control
animations()
while True:
bird_vely += 1
birdy += bird_vely
for event in pygame.event.get():
if ( event.type == pygame.KEYDOWN
and event.key == pygame.K_UP):
bird_vely = -10
if event.type == pygame.QUIT:
pygame.quit()
draw_object()
display_update()
Well you do so by implementing below code snippet in your code:
running = True
while running:
# other code
event = pygame.event.wait ()
if event.type == pygame.QUIT:
running = False # Be interpreter friendly
pygame.quit()
Make sure that you call pygame.quit() before you exit your main function
You can also reference this thread
Pygame escape key to exit
You must terminate the application loop when the QUIT event occurs. You have implmented the QUIT event, but you don't terminate the loop. Add a variabel run = True and set run = False when the event occurs.
To terminate the game when ESC is pressed you have to implement the KEYDOWN event. Set run = False when the KEDOWN event occurs and event.key == pgame.K_ESC:
run = True
while run:
bird_vely += 1
birdy += bird_vely
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.KEYDOWN:
if event.key == pgame.K_ESC:
run = False
elif event.key == pygame.K_UP:
bird_vely = -10
draw_object()
display_update()
pygame.quit()
exit()
Whenever I try to run my program it freezes up and crashes. I'm not a master pygame coder, but I'm almost sure its something to do with my main loop. It's supposed to allow the user to move left and right using arrow keys. I've tried adding a clock and changing the size of the screen but that didn't work. Here is the code:
import pygame
import sys
import random
import time
pygame.init()
screen = pygame.display.set_mode((500,500))
events = pygame.event.get()
clock = pygame.time.Clock()
x = 50
y = 50
game_over = False
while not game_over:
for event in events:
if event.type != pygame.QUIT:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
x += 5
elif event.key == pygame.K_LEFT:
x -= 5
else:
sys.exit()
screen.fill((0,0,0))
pygame.draw.rect(screen, (255,255,255), (x,y,50,50))
clock.tick(30)
pygame.display.update()
The code needs to process the event queue continuously, otherwise your operating environment will consider your window to be non-responsive (locked up). Your code is almost there, except it only fetches the new events once, but this needs to be done every iteration of the main loop.
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((500,500))
clock = pygame.time.Clock()
x = 50
y = 50
game_over = False
while not game_over:
events = pygame.event.get() # <<-- HERE handle every time
for event in events:
if event.type != pygame.QUIT:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
x += 5
elif event.key == pygame.K_LEFT:
x -= 5
else:
sys.exit()
screen.fill((0,0,0))
pygame.draw.rect(screen, (255,255,255), (x,y,50,50))
clock.tick(30)
pygame.display.update()
You cant do foe event in events, as when you call pygame.events.get(), you are updating them, you are updating them once and looping over them every frame, you need to use for event in pygame.event.get(): so you are calling the function every frame and updating the events every frame
unless you were trying to do this?
events = pygame.event.get
...
for event in events():
which does the same as above
I have some python code that uses a pygame window to establish which key is being pressed. When a key is pressed, the code heads off and does things before coming back to see what the next key pressed might be.
The problem I have is that if the user presses a key repeatedly, even while the 'code heads off and does things', pygame seems to remember what has been pressed rather than waiting for the next keypress. What I want is for the code to ignore any keypresses while the 'go and do stuff' is done then once that's finished, get the next keypress. Hope this makes sense!
import pygame
import time
pygame.init()
screen = pygame.display.set_mode((450,282))
screen.fill((0,0,0))
pygame.display.flip()
clock = pygame.time.Clock()
done = False
def go_and_do_things():
print("doing things")
time.sleep(2)
print("things done")
# Loop as long as done == False
while not done:
for event in pygame.event.get(): # User did something
if event.type == pygame.KEYDOWN:
keypressedcode = event.key # This is the ASCII code
print("keypressedcode is " + str(keypressedcode))
go_and_do_things()
elif event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
clock.tick(60)
time.sleep(4)
pygame.quit()
You could use pygame.event.clear. As written below, it will discard any keypresses during go_and_do_things().
while not done:
for event in pygame.event.get(): # User did something
# Any key down
if event.type == pygame.KEYDOWN:
keypressedcode = event.key # This is the ASCII code
print("keypressedcode is " + str(keypressedcode))
go_and_do_things()
pygame.event.clear(eventtype=[pygame.KEYDOWN,
pygame.KEYUP)
elif event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
clock.tick(60)
This is a fairly simple problem, you just need to add another
event.type for keyup. You also need to add a variable to make it stop
running which I will label as stopV if event.type == pygame.KEYUP:
stopV = True This should let you instantly stop it when you want to. edit because I want to reword this:
Re-doing this to make it more clear.
import pygame
import time
pygame.init()
screen = pygame.display.set_mode((450,282))
screen.fill((0,0,0))
pygame.display.flip()
clock = pygame.time.Clock()
done = False
unClick = False
def go_and_do_things():
if unClick == False
print("hello")
# do anything you want in the function here
else
return
while not done:
for event in pygame.event.get(): # User did something
# Any key down
if event.type == pygame.KEYDOWN:
keypressedcode = event.key # This is the ASCII code
print("keypressedcode is " + str(keypressedcode))
go_and_do_things()
if event.type == pygame.KEYUP:
unClick == True
elif event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
clock.tick(60)
I am trying to increase my speed variable in my pygame code. But as i run this piece of code the speed remain 0.1 (if i press UP key) and 0 (else case). I am unable to debug this. Any help in this would be greatly appreciated.
import pygame
speed = 0
screen = pygame.display.set_mode((400,400),0,32)
pygame.display.update()
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
if speed < 8 :
speed+=0.1
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
if speed > 0 :
speed+= -0.1
pygame.display.update()
print(speed)
clock.tick(60)
pygame.quit()
quit()
You are confusing the event KEYUP with the UP key. The event KEYUP occurs when a key (any key) is released. The event KEYDOWN occurs when any key is pressed down.
In you code, this means that when the UP key is pressed down, the speed is set to 0.1, and when the UP key is release, the speed is set to 0.0.
If you want the speed to keep increasing, and decreasing when a key is released, you should use a timer, like so:
import pygame
speed = 0
screen = pygame.display.set_mode((400,400),0,32)
pygame.display.update()
clock = pygame.time.Clock()
pygame.time.set_timer(pygame.USEREVENT+1, 20)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
if event.type == pygame.USEREVENT+1:
if pygame.key.get_pressed()[pygame.K_UP]:
if speed < 8 :
speed+=0.1
else:
if speed > 0.1:
speed+= -0.1
else:
speed = 0.0
pygame.display.update()
print(speed)
clock.tick(60)
pygame.quit()
quit()
Adjust the delay in the set_timer to suit your taste. Also, note the addition to reset the speed to zero. Float operations are not completely exact, so repeated adding and substracting can lead to a 'zero' that is negative.
The way I've seen this done is:
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_UP]:
if speed < 8:
speed += 0.1
if keys_pressed[pygame.K_DOWN]:
if speed > 0:
speed += -0.1