[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.