1

Reading this Pygame question made me wonder why, if I want to check whether the shift key is pressed (simultaneously with another key), I have to write something like

if event.key == K_s:
    if event.mod & KMOD_SHIFT:
        ...

and in particular, while I do understand perfectly why this code fragment isn't equivalent to the other one in the question, I am wondering what the reason is for a bit-to-bit comparison, which seems a bit weird in this context, where we're basically just checking if two events occur at the same time.

The value of mod seems to always be 1 when shift is pressed, and at least at a first glance the docs seem not to provide any explanation for using &.

Edit: this has been marked as a duplicate of this other question but it obviously isn't, as

  • this is specific to pygame
  • I had already taken a look and it was not at all as helpful as the answer I got, as the answers mostly deal with the more theorical aspects of the question
harisont
  • 143
  • 1
  • 9
  • 1
    From the second answer to the linked duplicate: *"& is used to test or clear a certain bit"*. In this case it's testing whether the `KMOD_SHIFT` bit(s) are 1 or 0 in `event.mod`. – kaya3 Dec 09 '20 at 15:41
  • @kaya3 yes, I see how the two questions are related, but my question was more about why pygame does things this way than about & per se. – harisont Dec 09 '20 at 15:48

1 Answers1

3

There See pygame.key:

The keyboard also has a list of modifier states (from pygame.localspygame constants) that can be assembled by bitwise-ORing them together.

The modifier states (KMOD_LSHIFT, KMOD_RSHIFT, KMOD_LCTRL, KMOD_RCTRL, ...) are represented by a single bit. The states are encoded in event.mod. Since several states can be True at the same time, several bits of event.mod can be set at the same time. Hence, you need to use the binary AND (&) operator to mask the bit.

The KMOD_SHIFT state is the combination (OR) of the KMOD_LSHIFT and KMOD_RSHIFT states. This means that KMOD_SHIFT is the same as KMOD_LSHIFT | KMOD_RSHIFT.

Hence the condition

if event.mod & KMOD_SHIFT:

is the same as

if event.mod & (KMOD_LSHIFT | KMOD_RSHIFT):

and the same as:

if (event.mod & KMOD_LSHIFT) or (event.mod & KMOD_RSHIFT):
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • 1
    I see! Great answer, now I understand both why it makes sense (which I had already understood thanks to @Carcigenicate's comment) and why it is necessary. Thanks a lot! – harisont Dec 09 '20 at 15:28