How do I get a user keyboard input with python and print the name of that key ?
e.g:
user clicked on "SPACE" and output is "SPACE"
user clicked on "CTRL" and output is "CTRL".
for better understanding i'm using pygame libary. and i built setting controller for my game. its worked fine but i'm able to use only keys on my dict. i dont know how to add the other keyboard keys.
see example:
class KeyboardSettings():
def __init__(self,description,keyboard):
self.keyboard = keyboard
self.default = keyboard
self.description = description
self.active = False
def activate_change(self,x,y):
fixed_rect = self.rect.move(x_fix,y_fix)
pos = pygame.mouse.get_pos()
if fixed_rect.collidepoint((pos)):
if pygame.mouse.get_pressed()[0]:
self.active = True
elif pygame.mouse.get_pressed()[0]:
self.active = False
This is a part of my class. in my script i loading all related object to that class. the related object are the optional keys in the game.
e.g
SHOOT1 = KeyboardSettings("SHOOT","q")
move_right = KeyboardSettings("move_right","d")
#and more keys
key_obj_lst = [SHOOT1,move_right....]
#also i built a dict a-z, 0,9
dict_key = { 'a' : pygame.K_a,
'b' : pygame.K_b,
'c' : pygame.K_c,
...
'z' : pygame.K_z,
'0' : pygame.K_0,
...
'1' : pygame.K_1,
'9' : pygame.K_9,
then in game loop:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
for k in key_obj_lst:
#define each key by user
if k.active:
k.keyboard = event.unicode
default = False
if k.keyboard in dict_key:
if event.key == dict_key[k.keyboard]:
if k.description == 'Moving Right':
moving_right = True
if k.description == 'SHOOT':
SHOOT = True
The code worked perfectly but i trully dont know how to add keys that not letters and numbers such as "ENTER","SPACE" etc.
pygame provides a function for getting the name of the key pressed:
pygame.key.name
And so you can use it to get the name of the key, there is no need to use a dictionary for this:
import pygame
pygame.init()
screen = pygame.display.set_mode((500, 400))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
if event.type == pygame.KEYDOWN:
key_name = pygame.key.name(event.key)
print(key_name)
pip install keyboard
import keyboard #use keyboard module
while True:
if keyboard.is_pressed('SPACE'):
print('You pressed SPACE!')
break
elif keyboard.is_pressed("ENTER"):
print("You pressed ENTER.")
break
Use keyboard module
import keyboard
while True:
print(f"You pressed {keyboard.get_hotkey_name()})
Related
i am trying to detect which button is being pressed from my controller and when it is released.
This is how far i have managed to get.
import pygame
pygame.init()
j = pygame.joystick.Joystick(0)
j.init()
try:
while True:
events = pygame.event.get()
for event in events:
if event.type == pygame.JOYBUTTONDOWN:
if j.get_button(1):
print("x")
elif j.get_button(2):
print("a")
elif event.type == pygame.JOYBUTTONUP:
print("button released")
except KeyboardInterrupt:
print("EXITING NOW")
j.quit()
i am new to programming and i dont entirely understand this piece of code.
this detects if x or a is being pressed and if any button is being released. I want it to detect if x or a is being pressed and when they are released.
Thanks for reading!
pygame.event.get() returns a list of events(events are a type of structure/object of pygame generated when the user does something moves mouse / presses buttons e.t.c.).then for each of those events you check if the they are the event you want(pygame.JOYBUTTONDOWN or event.type,pygame.JOYBUTTONUP).
you can only check if a button is pressed and then see which button is pressed.
if event.type == pygame.JOYBUTTONDOWN:
if j.get_button(1):
print("x")
elif j.get_button(2):
print("a")
to see when buttons get released best way i can think off is having a list of Button Status .When the status for a button changes you do something .
ButtonStatus[2];
ButtonStatus[0]=get_button(1);#a
ButtonStatus[1]=get_button(2);#x
if event.type == pygame.JOYBUTTONUP:
if ButtonStatus[0]!=get_button(1)
#status changed do yr code for button release a
pass;
if ButtonStatus[1]!=get_button(2)
#status changed do yr code for button release b
pass;
above code is a sample not actually compiled . general idea is to check when a button is released,check which button changes status and execute code accordingly.
So, i coded what i needed with the help of the other answers!
import pygame
pygame.init()
j = pygame.joystick.Joystick(0)
j.init()
r = 2
t = 5
b = 1
x = 3
try:
while True:
events = pygame.event.get()
for event in events:
if event.type == pygame.JOYBUTTONDOWN:
if j.get_button(1):
print("B")
b = 2
elif j.get_button(2):
print("X")
x = 5
elif event.type == pygame.JOYBUTTONUP:
if b == r :
print("b2")
b = 1
if x == t:
print("x2")
x = 3
except KeyboardInterrupt:
print("EXITING NOW")
j.quit()
This isn't robust in any way. You need to make new strings for every button you need.
You do that by copying the button with the biggest variables and just adding 3 to every variable in the code you coppied. Please answer the original post if you can give a better answer (which probably exists).Also, when u press multiple buttons at the same time and u release atleast one it thinks you have realeased all of them.
So basically I'm making a quiz game in which the user must "lock in" their answer. In order to do that the user must press a certain key while pressing another. For example: holding the "w" key while pressing and letting go of the space bar.But when I try to achieve this, nothing happens. Here is what I have so far:
if (event.type == pygame.KEYDOWN) and (event.key == pygame.K_w) and (event.type == pygame.KEYUP) and (event.key == pygame.K_SPACE):
print(1)
why doesn't this work?
One way is to use pygame.key.get_pressed(). Example -
keys = pygame.keys.get_pressed()
if keys[pygame.K_w] and keys[pygame.K_SPACE]:
print(1)
EDIT : This is how I implemented it -
#!/usr/bin/python3
import pygame
from pygame.locals import *
from sys import exit
#initializing variables
pygame.init()
screen=pygame.display.set_mode((640,480),0,24)
pygame.display.set_caption("Key Press Test")
f1=pygame.font.SysFont("comicsansms",24)
#main loop which displays the pressed keys on the screen
while True:
for i in pygame.event.get():
a=100
screen.fill((255,255,255))
if pygame.key.get_focused():
press=pygame.key.get_pressed()
# checking if they are pressed at the same time or not.
if press[pygame.K_w] and press[pygame.K_SPACE]:
print (1)
for i in xrange(0,len(press)):
if press[i]==1:
name=pygame.key.name(i)
text=f1.render(name,True,(0,0,0))
screen.blit(text,(100,a))
a=a+100
pygame.display.update()
question_num = general_knowlege_questions[0]
keys = pygame.key.get_pressed()
if keys[pygame.K_w] and (General_knowledge[question_num][5] == "a"):
test = 1
if keys[pygame.K_d] and (General_knowledge[question_num][5] == "b"):
test = 1
if keys[pygame.K_s] and (General_knowledge[question_num][5] == "c"):
test = 1
if keys[pygame.K_a] and (General_knowledge[question_num][5] == "d"):
test = 1
so basically this is my code to recognize my answer for the quiz, but it ends up not recognizing the correct answer. Btw the General_knowledge variable is a list, question number is self explanitory and 5 is the index that contains the answer.
so im building a pi based robot.
It uses a ps3 controller for input. When the X button is pressed, it takes a photo. For some reason, it takes around 5 shots at a time. Is there a way to bounce the input so it only recognises one press?
I'm assuming it's registering multiple presses each time... Part of the code is attached, but I must state most of it is used from piborg.org
joystick = pygame.joystick.Joystick(0)
button_take_picture = 14 # X button
while running:
# Get the latest events from the system
hadEvent = False
events = pygame.event.get()
# Handle each event individually
for event in events:
if event.type == pygame.QUIT:
# User exit
running = False
elif event.type == pygame.JOYBUTTONDOWN:
# A button on the joystick just got pushed down
hadEvent = True
elif event.type == pygame.JOYAXISMOTION:
# A joystick has been moved
hadEvent = True
if hadEvent:
if joystick.get_button(button_take_picture):
take_picture()
What seems to be happening is that the X button stays down for multiple frames. Some other events might happen during this time, causing a call to take_picture() in your code for every frame. To fix this, you can either call take_picture() only on JOYBUTTONUP (when the button is released), or move the if joystick.get_button(button_take_picture) part to inside the pygame.JOYBUTTONDOWN section.
Alternatively, you could use another variable to indicate whether the picture was already taken, like this:
picture_was_taken = False
while running:
hadEvent = False
events = pygame.event.get()
for event in events:
...
if event.type == pygame.JOYBUTTONUP:
if not joystick.get_button(button_take_picture)
picture_was_taken = False
...
if hadEvent:
if joystick.get_button(button_take_picture) and not picture_was_taken:
take_picture()
picture_was_taken = True
I'm working on an RPG and after completing my first map, I had to put the possibility of passing from one to another because I don't want to use scrolling.
Actually I check if the position of my character is the same as a particular sprite (door, invisible block, etc.) and then doing the change of the font and the loading of the new *.txt file. But the problem is that the previous sprites are still there!
I checked some way to solve this problem and a lot of people said that I should use the fill() function to overlay the screen. It works but the old sprites are still there; if my character tries to go to where a wall was, he can't.
I also try emptying the list of the sprites but it crashes the game instead, as the character was in this list, even if I reload the character...
It's the only thing blocking me to achieve a test version of the universe, if anyone could help me..
Here is my game loop :
while continuer_jeu:
#Limit the speed
pygame.time.Clock().tick(30)
for event in pygame.event.get():
if event.type == QUIT:
continuer_jeu=0
continuer_accueil=0
continuer_rules=0
continuer=0
carte=0
if event.type == KEYDOWN:
#If user press escape => back to the title screen
if event.key == K_ESCAPE:
continuer_jeu = 0
#Chara's moving key
elif event.key == K_RIGHT:
Noc.deplacer('droite')
elif event.key == K_LEFT:
Noc.deplacer('gauche')
elif event.key == K_UP:
Noc.deplacer('haut')
elif event.key == K_DOWN:
Noc.deplacer('bas')
#Refresh with new positions
fenetre.blit(fond, (0,0))
niveau.afficher(fenetre)
fenetre.blit(Noc.direction, (Noc.x, Noc.y))
pygame.display.flip()
if niveau.structure[Noc.case_y][Noc.case_x] == 'ma6': #If going through a door
if carte == "n1": # if first map
fond = pygame.image.load(image_Interieur).convert()
niveau = Niveau("Maison") #Load the house sprites
niveau.generer()
niveau.afficher(fenetre)
fenetre.blit(fond,(0,0))
If you need more of the code, just ask.
I achieve to pass from a map to another by deleting the previous list, load an other one and then recreate the character :
if niveau.structure[Noc.case_y][Noc.case_x] == "up" :
if carte == "n1" :
fond = pygame.image.load(image_Map2).convert()
niveau = Niveau("n2")
niveau.reset()
niveau.generer()
niveau.afficher(fenetre)
Noc = Perso("image/Noc right.png", "image/Noc left.png","image/Noc face.png", "image/Noc back.png", niveau)
fenetre.blit(fond,(0,0))
carte = "n2"
if niveau.structure[Noc.case_y][Noc.case_x] == "down" :
if carte == "n2" :
fond = pygame.image.load(image_Map1).convert()
niveau = Niveau("n1")
niveau.reset()
niveau.generer()
niveau.afficher(fenetre)
Noc = Perso("image/Noc right.png", "image/Noc left.png","image/Noc face.png", "image/Noc back.png", niveau)
fenetre.blit(fond,(0,0))
carte = "n1"
with theses functions :
class Niveau:
def __init__(self, fichier):
self.fichier = fichier
self.structure = 0
def reset(self):
self.structure = []
def generer(self):
with open(self.fichier) as fichier:
self.structure = [ligne.split() for ligne in fichier]
But I got an other problem : I can't change the map a second time. On the 2nd map, the character reach a down case, nothing happend. I tried to put the instruction when it is "down" on a "up" + "if carte == "n2" but the character came back to his spawn position... Where could I have made mistakes ?
I need to kb input onto a pygame screen
at the moment it appears on the idle shell
any advice would be appreciated.
This code is extracted from a larger program
mostly screen based but i need to input some
data (numeric) from the kb at times
import sys
import pygame
from pygame.locals import *
pygame.init()
N= ''
screen = pygame.display.set_mode((600,600))
font= pygame.font.Font(None,40)
screen.fill((255,255,255))
pygame.display.flip
pygame.display.update()
def score(C,y):
SetWnd = font.render( C,True,(0,0,255))
screen.blit(SetWnd, (15, 100+y))
pygame.display.update()
def start():
while True:
name=''
for evt in pygame.event.get():
if evt.type == KEYDOWN:
if evt.unicode.isalnum(): # unicode
name+=evt.unicode
print name,
elif evt.key == K_BACKSPACE:
name = name[:-1]
print name,
elif evt.key == K_RETURN:
return N
elif evt.type == QUIT:
pygame.quit()
sys.exit()
def Pchange(c,y):
block = font.render(N, True, (0,0,0))
rect = block.get_rect()
rect.move_ip(75,100 + y)
screen.blit(block,rect)
pygame.display.flip()
score('wind', 0)
score('elev',20)
N = start()
Pchange(N,0)
Pchange(N,20)
Firstly you draw the score twice, which i assume works well.
The problem lies in you start function.
You are not calling any draw or update function in your while loop.
In your event foreach, you add a digit to name, and exit the while loop when enter is pressed. Then you draw twice with Pchange, but you are the function does not use the right parameters. You have:
def Pchange(c,y):
block = font.render(N, True, (0,0,0))
you are using the global N which is ''. So to fix that, you need to change N to c.
The next problem is that the game quits right after pressing enter. Since you pasted only a part of the program, this might not be the case. If it is, make another while loop, and just wait for the ESC key to call pygame.quit() and sys.exit()