I have just downloaded pygame 1.9.2 for python 3.3 and the keydown function is not working. The IDLE shell keeps telling me the same error:
NameError: name 'KEYDOWN' is not defined
How do I solve this problem? I am kinda new to programming so could you please explain this to me.
NOTE: Sorry for deleting my previous answer but Stack Overflow just randomly posted my answer before I was done.
Well, there could be several things wrong. You could be using pygame.key.keydown(), which is wrong, and you should be using pygame.key.get_pressed().
But what I suspect is wrong with your code is that you're not using pygame.KEYDOWN properly.
If you're trying to do something while a key is being held down, use pygame.key.get_pressed(), and do something like this:
key = pygame.key.get_pressed()
if key[pygame.K_WHATEVER_KEY_YOU_WANT]:
# do code
and just repeat that for every key you want to check.
If you're just trying to check if a key is being pressed, use pygame.KEYDOWN with an if statement, then check if the key you want is being pressed in a nested if statement under the first if statement. Like so:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_WHATEVER_KEY_YOU_WANT:
#do code
I'm assuming you have an event variable your using to iterate over pygame.event.get() function that 'gets' events. If not then here is the code above in a game/window loop:
running = True # variable to control while loop
while running: # while the variable running is equal to true
for event in pygame.event.get(): # use the variable 'event' to iterate over user events
if event.type == pygame.QUIT: # test if the user is trying to close the window
running = False # break the loop if the user is trying to close the window
pygame.quit() # de-initialize pygame module
quit() # quit() the IDE shell
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_WHATEVER_KEY_YOU_WANT:
#do code
This is basically how you use pygame.KEYDOWN. It's probably not the only way however. I recommend (since you're new to programming) to read the pygame docs on their official website for more info about checking key input in pygame. And read some of the answers to this question.
Related
My program used to run the following bit of code and it worked perfectly when i pressed left shift. But as of today it suddenly stopped working, no code changed, no reinstalls, no updates since it was working and stopped working.
#running on windows 10
while True:
for event in pygame.event.get():
if event.type == KEYDOWN:
print(event)
if event.key == 304:#left shift
print("worked")
the output of print(event) used to be :
<Event(768-KeyDown {'unicode': '', 'key': 304, 'mod': 4096,
'scancode': 79, 'window': None})> now it is : <Event(768-KeyDown
{'unicode': '', 'key': 1073742049, 'mod': 4096, 'scancode': 79,
'window': None})>
I know how to fix it, or do it in a different way, but does someone know the reason the 'key' is suddenly a ridiculous number? Is there something wrong with my computer that the key values it's giving is messed up?
It would help if you didn`t write the key codes on your own. It will be better if you use the predefined pygame key, for example:
while True:
for event in pygame.event.get():
if event.type == KEYDOWN:
print(event)
if event.key == pygame.K_LSHIFT:
print("worked")
Here is a list of pygame`s predefined keys.
pygame documentation - pygame.key
Use pygame.K_LEFT if you want to detect if LEFT is pressed.
Let me refer to the documentation of the pygame.key module:
Portability note: The integers for key constants differ between pygame 1 and 2. Always use key constants (K_a) rather than integers directly (97) so that your key handling code works well on both pygame 1 and pygame 2.
A user friendly name of a key can be get by pygame.key.name():
Get the descriptive name of the button from a keyboard button id constant.
The keyboard events KEYDOWN and KEYUP (see pygame.event module) create a pygame.event.Event object with additional attributes. The key that was pressed can be obtained from the key attribute. The unicode attribute provides the Unicode representation of the keyboard input.
I've been trying to develop a "text box" class for pygame as a little personal project, and I've come across an issue that's really stumped me. I'm trying to expand on the pygame text input class found here, wrapping it in a text box class that supports multiple lines and, hopefully, scrolling capabilities.
My problem comes when trying to move the blinker up and down between the lines of text. Basically, hitting the "up" arrow once moves the blinker all the way to the top, and then it stops being responsive to move it down.
Here's the code for how I give the pygame_textbox class the events:
while True:
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
test_box.update(events)
test_box_2.update(events)
test_box.draw(screen, (100, 100))
test_box_2.draw(screen, (200, 250))
pygame.display.update()
Here's the code for the text box class (event comes from the above code):
if event.type == pl.KEYDOWN:
if self.is_active:
print("reading in text box: {}".format(event))
if event.key == pl.K_UP and self.cursor_line > 0:
self.cursor_line -= 1
print("cursor going UP to {}".format(self.cursor_line))
if event.key == pl.K_DOWN and self.cursor_line < len(self.text_input)-1:
self.cursor_line += 1
print("cursor going DOWN to {}".format(self.cursor_line))
if event.key == pl.K_RETURN:
self.text_input.insert(self.cursor_line+1, pygame_textinput.TextInput())
self.cursor_line += 1
for line in self.text_input:
print(line.input_string)
Trying to debug it seems to show that the pygame.event.get() queue is taking in way more KEYDOWN events than it's supposed to; one press of the button sends multiple (and sometimes ongoing) events. I'm new to pygame, but I'm pretty sure that's not supposed to happen with KEYDOWN events, right? There's only supposed to be one event triggered every time a key is pressed. What am I doing wrong here? Is this a bug with pygame itself?
Thanks for any help you can provide. I'm fairly new at this and I hope I formatted the question right.
Just take a look at the pygame_textinput module you linked in your question:
# Update key counters:
for key in self.keyrepeat_counters:
self.keyrepeat_counters[key][0] += self.clock.get_time() # Update clock
# Generate new key events if enough time has passed:
if self.keyrepeat_counters[key][0] >= self.keyrepeat_intial_interval_ms:
self.keyrepeat_counters[key][0] = (
self.keyrepeat_intial_interval_ms
- self.keyrepeat_interval_ms
)
event_key, event_unicode = key, self.keyrepeat_counters[key][1]
pygame.event.post(pygame.event.Event(pl.KEYDOWN, key=event_key, unicode=event_unicode))
As you can see, it's the update method of the TextInput that repeats the key events by posting them again to pygame's event queue.
Is there a really simple way of knowing if the key SPACE is currently DOWN. I'm making a basic snake game and I don't know to use pygame and I can't find it anywhere.
I imagine it like something along these lines:
if K_SPACE = DOWN:
turtle.turn(90)
thank you for any help
In your game loop:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
turtle.turn(90)
I am having trouble trying to grasp a couple of things inside the py game code, firstly why are there two types of quit or are these the same? for example:
pygame.QUIT
pygame.quit()
Also I can't grasp this small piece code fully:
for event in pygame.event.get():
if event.type == pygame.QUIT:
I understand the first line of code, but I don't understand event.type?, is .type a function inside of pygame or python in general? what does it do?
pygame.QUIT
Is an enumeration for an input that signals for the program to quit
pygame.quit()
Is a function call to unload pygame modules. According to the docs it won't actually quit the game:
http://www.pygame.org/docs/ref/pygame.html#pygame.quit
You could use sys.exit(0) for that.
This loop here:
for event in pygame.event.get():
if event.type == pygame.QUIT:
Checks each event, if one of them has the value pygame.QUIT then some exit code should follow.
pygame.QUIT is simply a constant, while pygame.quit() is a function within the pygame module that uninitializes it. The fragment of code:
for event in pygame.event.get():
if event.type == pygame.QUIT:
...
is part of the typical control loop of a pygame program. The method pygame.event.get() returns the next event. If the type of event (an attribute of the event object) is pygame.QUIT then the application should do what is necessary to exit, including possibly calling pygame.quit().
The manual for pygame.quit() says:
Uninitialize all pygame modules that have previously been initialized. When the Python interpreter shuts down, this method is called regardless, so your program should not need it, except when it wants to terminate its pygame resources and continue.
So you should normally call this method yourself.
pygame.QUIT is a so called event type. Pygame uses events to tell you something happened. The code checks each events in the queue and checks if a QUIT event happened.
event.type is something from pygame, and it tells you what type of event it is. By comparing it to pygame.QUIT, you can check if the quit() method has been called, and take steps to shutdown the game.
First the background: I use Python and PyGame. I've experimented with writing my own input/controller module, that allows users to remap controls in any way they like. This necessarily requires that my code be written to handle different types of input (for example, keyboard keys, controller buttons, and controller axes/hats/etc.)
For example, if the button "Right" is mapped to an arrow key, the code to handle GetPush("Right") or GetRelease("Right") would be somewhat different than if it were mapped to a control stick being pushed along a certain axis. To help take care of this, I made a helper function __GetButtonType() which -- as the name replies -- returns what type of button it is. For the code shown here, buttons are referred to as strings. The first letter of the string denotes the button type, and the rest denotes the button. For example k97 refers to the keyboard key with a value of 97. (the A key.)
Now for the issue at hand. My code does what I want it to do. But as I began cleaning it up, I came across one part that bothered me. I have the following segment of code which handles presses from the keyboard. (The DoSomething() functions replace entirely unrelated code, that I assume does not matter for the question at hand.)
for n in TheController.ControlMap:
if __GetButtonType(n)=="key":
if event.type == KEYUP:
if event.key == int(n[1:]): DoSomething()
if event.type == KEYDOWN:
if event.key == int(n[1:]): DoSomethingElse()
Something about this just looks a little off to me. It may be that the if event.key == int(n[1:]) condition is repeated. That seems wasteful. However, if event.key is not KEYUP or KEYDOWN, then the event will not have a key attribute (that is how pyGame works, that isn't of my design.) This means that the condition if (event.type == KEYDOWN and event.key == int(n[1:]) will throw an error whenever the event.type is something else.
However, I thought about it a bit, and realized that I CAN shorten the code by one line by structuring it in the following way:
for n in TheController.ControlMap:
if event.type == KEYUP:
if __GetButtonType(n)=="key" and event.key == int(n[1:]): DoSomething()
if event.type == KEYDOWN:
if __GetButtonType(n)=="key" and event.key == int(n[1:]): DoSomethingElse()
Both code snippets work. Both do the same thing. The first one looks a bit easier to read, but not by a whole lot. The second one uses fewer lines. My question is this:
Which style is "better"? Does one perform faster than the other one would by a non-negligible amount? Or is one just considered "poor practice?" Maybe they both are, in fact. I am still relatively new to programming.
Thank you,
Chris
Both of your statements have one same feature which would make people cringe. Equivalent if statements are repeated twice. This is no good because it clatters your code and is absolutely unnecessary:
if event.type in [KEYUP, KEYDOWN] and __GetButtonType(n)=="key" and event.key == int(n[1:]):
if event.type == KEYUP:
DoSomething()
elif event.type == KEYDOWN:
DoSomethingElse()
Here the first condition makes sure that you don't get an error on event.key.
Also use elif because the options are mutually exclusive. Simple else will also suffice, but I'd leave elif for the purpose of readability. Also you can hide this into DoSomething(event.type).
Another option which could look ugly or pretty depending on who you ask is collapse it all into a flat if-else:
if event.type in [KEYUP, KEYDOWN] and __GetButtonType(n)=="key" and event.key == int(n[1:]):
(DoSomething if event.type == KEYUP else DoSomethingElse)()
But that's getting a bit weird... Still, it works.
Performance-wise, there is absolutely nothing to worry about here. Optimization is a whole other topic and the first thing to optimize would be program design / algorithm rather than local low-importance commands.
on the lines of what 'sashkello' mentioned, I generally have the below block of code common in my pygame programs.
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT :
do_something()
elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
do_something_else()