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

Re: [pygame] Capturing Multiple Keyboard Inputs



On 1/16/2012 11:35 AM, Radomir Dopieralski wrote:
> On Mon, Jan 16, 2012 at 20:22, Silver <rockachu2@xxxxxxxxx> wrote:
>> On 1/15/2012 8:16 PM, Ian Mallett wrote:
>>> On Sun, Jan 15, 2012 at 7:46 PM, Ryan Strunk <ryan.strunk@xxxxxxxxx> wrote:
>>>
>>>> Hello everyone,
>>>> I am testing my understanding of the pygame.key module by creating a
>>>> program
>>>> that pans the sound of a car engine and raises/lowers its frequency. While
>>>> the individual keys do exactly what they're supposed to, I run into a big
>>>> problem when I try to do two things at once. For example, if I hold the up
>>>> arrow, the frequency of the sound rises with no problem. If I then hold
>>>> down
>>>> the left arrow while still holding up, however, the frequency stops rising
>>>> and the pan begins to adjust itself. How can I make both keys carry out
>>>> their assigned task at the same time?
>>>> As a side note, aside from exporting the redundant code below into its own
>>>> methods, are there any other ways to check for multiple keys without giving
>>>> each its own if check?
>>>> Ugly code is below:
>>>>
>>>> import pygame
>>>> from sound_lib.stream import FileStream
>>>> from sound_lib.output import Output
>>>>
>>>> def main():
>>>>        clock = pygame.time.Clock()
>>>>        o = Output()
>>>>        sound = FileStream(file="sounds/car.wav")
>>>>        screen = pygame.display.set_mode((640, 400))
>>>>        sound.looping = True
>>>>        sound.play()
>>>>        pygame.key.set_repeat(50, 50)
>>>>        while(True):
>>>>                for event in pygame.event.get():
>>>>                        if event.type == pygame.KEYDOWN:
>>>>                                if event.key == pygame.K_UP:
>>>>                                        sound.frequency += 200
>>>>                                if event.key == pygame.K_DOWN:
>>>>                                        sound.frequency -= 200
>>>>                                if event.key == pygame.K_LEFT:
>>>>                                        if sound.pan <= -0.9:
>>>>                                                sound.pan = -0.9
>>>>                                        else:
>>>>                                                sound.pan -= 0.1
>>>>                                if event.key == pygame.K_RIGHT:
>>>>                                        if sound.pan >= 0.9:
>>>>                                                sound.pan = 0.9
>>>>                                        else:
>>>>                                                sound.pan += 0.1
>>>>                                if event.key == pygame.K_ESCAPE:
>>>>                                        exit()
>>>>                clock.tick(10)
>>>>
>>>> if __name__ == '__main__':
>>>>        main()
>>>>
>>>> Thanks,
>>>> Ryan
>>>>
>>> You should use pygame.key.get_pressed() to check whether the left/up keys
>>> are pressed.  Something like:
>>>
>>> while pygame.event.get(): pass
>>> key = pygame.key.get_pressed()
>>> if key[K_LEFT]: #whatever
>>> if key[K_UP]: #whatever
>>>
>>> Ian
>>
>> OK, I am seriously confuzzled here. I thought that pygame.event.get()
>> gave you all the events, and that his code SHOULD capture multiple
>> keypresses.
> 
> It gives you all events. You get the even for pressing the first key,
> and you get the event for pressing the second key.
> You also get the events for releasing those keys later on. You can
> keep track of which keys are pressed that way, but pygame does that
> for you internally, so you can just get the state of all the keys with
> get_pressed, which is more convenient.
> 
>> What is the difference between get_pressed and event.get()?
> 
> The former gives you the states of all the keys (including keys like
> shift and ctrl), the latter gives you an event from the event queue.
> 
>> Oh, and would the key repeat be worth doing manually to see if that is
>> the issue?
> 
> If your game depends on the timing of those repeats, you will most
> certainly want to use pygame.Clock and do your own timing, instead of
> relying on event.get and the operating system's key repeat.
> 
>> soemthing like:
>>
>> waspressed = []
>> thisframepressed = []
>>
>> every frame:
>>        thisframepressed = []
>>        if event.key in waspressed:
>>                ## trigger again
>>                thisframepressed.append(event.key)
>>        else:
>>                waspressed.append(event.key)
>>        for i in waspressed:
>>                if not i in thisframepressed:
>>                        waspressed.remove(i)
> 
> No, don't use events for that. Just run your main loop at a constant
> FPS with pygame.Clock and check for the key states with get_pressed
> regularly. Don't forget to pump the events though, or the window will
> become unresponsive.
Thanks a lot.