[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Problems with events and keys



lol... I forgot to tell it to accept spacebar input :P

This is coming along quite well. Soon I'll start coding the shoot-em-up game part of this... then it'll get really interesting.

I noticed that certain punctuation didn't work but I'm not worried about those. The game probably won't use any punctuation and if it does, it's a simple fix.

Anyway, here's what I've got now. Much better now, isn't it? I'm making a backup of this code so I can show my teachers. I also have to change the location of the text that got stuck all in the middle... but that shouldn't be too much trouble...

Next week I'll be able to put that helpers.py file to some good use, hopefully... ;P

On 2/8/07, Charles Christie < sonicbhoc@xxxxxxxxx> wrote:
That's exactly what I was looking for! But I couldn't find the " unicode.isalpha" or anything like that in the docs...

I knew I had to just make the event not pass anything to the textsprite class I just didn't know how to exclude keys without explicitly defining which ones I wanted and which ones I didn't. Thank you so much, man! I owe you!


On 2/8/07, Luke Paireepinart < rabidpoobear@xxxxxxxxx> wrote:
Charles Christie wrote:
> Oh wait, what I was thinking for was something completely different. I
> actually have no clue on how to restrict the textsprite class to only
> accept letters, numbers and keypad strokes simply and cleanly. I could
> just go and make a looooooong if/else statement that either has all
> the keys I want or all the keys I don't want to respond to... either
> way looks really long and painful >.<
>
> Please let me rephrase my question: Is there a clean way to make my
> program only accept letters, numbers and number pad input and ignore
> everything else?

I'll try to explain the process i went through to do this.
Okay.  First thing i think when i want to solve this problem is 'what is
in the event object that might help us with this?'
so i write the following script:

#DisplayKeydownEvents.py
import pygame
from pygame.locals import *
pygame.display.init()
screen = pygame.display.set_mode((640,480))

while 1:
    pygame.display.update()
    screen.fill((0,0,0),(0,0,640,480))
    for event in pygame.event.get ():
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pygame.quit()
                raise SystemExit
            else:
                print event
#------------------------
by pressing the various keys i see thai the event object has a key
called 'unicode' that contains the letter that i pressed.

The name 'unicode' seems to imply that the function may sometimes not
have a unicode and instead have a utf-8 or whatnot as its key, but a
quick search of pygame.org's documents reveals that

    KEYDOWN          unicode, key, mod

So now we know that we can check the 'unicode' attribute.

So in order to only get alphabetical items:

if event.type == KEYDOWN:
    if event.unicode.isalpha():
       print event.unicode

Ok we got that working.  Now for the numpad.
Unfortunately, there's not an 'isNumpad' function so let's examine the
events again.
By pressing the various numpad buttons we find their keycode is sequential.
There are two ways to go about it.
One way is, assuming you're using just the numpad digits and not the +,
-, etc...
is to realize that numpad 0 is 256 and numpad 9 is 265.
Obviously anything in this range will include the other numbers.
Another thing to notice: if the number is in this range, we can mod it
by 256, to get the number value.
So:
elif 256 <= event.key <= 265:
    print event.key % 256

As you can see, we don't deal with the events in your actual class, we
just don't pass anything to your textsprite unless it's something we
want to display.

We'd also like to check for number inputs.  fortunately we see that the
unicode value contains the actual number.
Hmm. what kind of methods do strings have to help us with this?
>>> dir('a')
['__add__', '__class__', '__contains__', '__delattr__', '__doc__',
'__eq__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__',
'__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__',
'__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__',
'__str__', 'capitalize', 'center', 'count', 'decode', 'encode',
'endswith', 'expandtabs', 'find', 'index', 'isalnum', 'isalpha',
'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust',
'lower', 'lstrip', 'replace', 'rfind', 'rindex', 'rjust', 'rsplit',
'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase',
'title', 'translate', 'upper', 'zfill']

Ah, okay. two methods interest us: isdigit and isalnum.
we can either add another elif clause or modify our original.  Modifying
the original is easier.
So it becomes:
if event.type == KEYDOWN:
    if event.unicode.isalnum():
       print event.unicode

Cool side effects that we get:
if they're holding shift then the unicode value will be capitalized so
we don't have to deal with the shift key.
the numpad key values are the same whether or not numlock is on.  if
this is a side effect you don't want you can check the event's 'mod'
attribute.  This is essentially a flag, but for some reason they use
large values.  2**13 for numlock, 2**14 for capslock, and they're adding
the values together.
Basically this means if event.mod == 4096 or event.mod == 12288 numlock
is down.

I thought it would help you more if you had the rationale behind the code.
I hope this helps you.
Final code is attached.
-Luke





Attachment: typinggame.py
Description: Binary data

Attachment: helpers.py
Description: Binary data