enrique2334
enrique2334

Reputation: 1059

How can I have two key_input methods in pygame?

I have found that I can only have one method for key input. Bellow I have two methods (movementsprite, and movementspritevert) I have found that I can only have one work. If I initiate both, the top one runs, and the second one does nothing. Is there a way around this? Am I doing something wrong?

Original Program

----Movement File------

    import pygame
    import os, sys
    from itertools import *
    from oryxsprites import *
    from oryxdisplay import *
    spritex = 320
    spritey = 320

    screen = pygame.display.set_mode((640, 640))
    def movementsprite():   

        global spritex

        keys = pygame.key.get_pressed()

        for event in pygame.event.get():
             if event.type == pygame.QUIT:
                 running = False
             elif event.type == pygame.KEYDOWN:

                 if event.key == pygame.K_RIGHT:
                     if spritex == 576:
                         spritex += 0
                     else:
                         spritex += 32 

                 elif event.key == pygame.K_LEFT:              
                     if spritex == 32:
                         spritex -= 0
                     else:
                         spritex -= 32

        return spritex
    def movementspritevert():   

        global spritey

        keys = pygame.key.get_pressed()

        for event in pygame.event.get():
             if event.type == pygame.QUIT:
                 running = False
             elif event.type == pygame.KEYDOWN:

                 if event.key == pygame.K_DOWN:
                     if spritey == 576:
                         spritey += 0
                     else:
                         spritey += 32 

                 elif event.key == pygame.K_UP:              
                     if spritey == 32:
                         spritey -= 0
                     else:
                         spritey -= 32

        return spritey

-------Main File------]

running = True

while running:

    backgroundmain()
    pygame.display.set_caption('OryxGame')
    #pygame.display.set_icon(grasstile)
    movementsprite()
    movementspritevert()

    pygame.display.flip()


    for event in pygame.event.get():
         if event.type == pygame.QUIT:
             running = False
             pygame.quit()

------Display file----

def backgroundmain():
    spritex = movementsprite()
    spritey = movementspritevert()
    backdrop = pygame.Rect(0, 0, 640, 640) 
    screen.fill((50,50,50))
    playingfeildwidth = (32, 608)
    playingfeildheight = (32, 608)

    screen.blit(warrior1, (spritex, spritey))

------Possible solution -------------

-Main File----

 while running:

    backgroundmain()
    pygame.display.set_caption('OryxGame')
    #pygame.display.set_icon(grasstile)
    movementsprite(events)
    movementspritevert(events)

    pygame.display.flip()


    for event in pygame.event.get():
         if event.type == pygame.QUIT:
             running = False
             pygame.quit()

-----Display File-----

def backgroundmain():
    events = pygame.event.get()
    spritex = movementsprite(events)
    spritey = movementspritevert(events)
    backdrop = pygame.Rect(0, 0, 640, 640) 
    screen.fill((50,50,50))
    playingfeildwidth = (32, 608)
    playingfeildheight = (32, 608)

------Key Input File-----------

spritex = 320
spritey = 320
screen = pygame.display.set_mode((640, 640))
def movementsprite(events):  
    global spritex
    keys = pygame.key.get_pressed()

    for event in events:
         if event.type == pygame.QUIT:
             running = False
         elif event.type == pygame.KEYDOWN:

             if event.key == pygame.K_RIGHT:
                 if spritex == 576:
                     spritex += 0
                 else:
                     spritex += 32 

             elif event.key == pygame.K_LEFT:              
                 if spritex == 32:
                     spritex -= 0
                 else:
                     spritex -= 32

    return spritex
def movementspritevert(events):   
    global spritey
    keys = pygame.key.get_pressed()

    for event in events:
         if event.type == pygame.QUIT:
             running = False
         elif event.type == pygame.KEYDOWN:

             if event.key == pygame.K_DOWN:
                 if spritey == 576:
                     spritey += 0
                 else:
                     spritey += 32 

             elif event.key == pygame.K_UP:              
                 if spritey == 32:
                     spritey -= 0
                 else:
                     spritey -= 32

    return spritey

---Error---

Traceback (most recent call last):
  File "C:\Users\Eric\Dropbox\oryxgame\oryxgame.py", line 12, in <module>
    backgroundmain()
  File "C:\Users\Eric\Dropbox\oryxgame\oryxdisplay.py", line 11, in backgroundmain
    spritey = movementspritevert(events)
TypeError: movementspritevert() takes no arguments (1 given)

----Full Code----

Upvotes: 0

Views: 296

Answers (1)

machow
machow

Reputation: 1072

The problem is that event.get() removes the events from queue (see docs). So, when your second function uses event.get(), there aren't any events remaining in the queue, unless they were able to slip in during the extremely short interval between calls.

To see this problem in action, put a print event after calling for event in pygame.event.get() in the first function, then try it in the second.

One way to fix this would be

    events = pygame.event.get()
    function1(events)
    function2(events)

Then use a for loop over events instead.


EDIT: to clarify how to implement

It's likely your code threw an error because pygame.event.get() was called before initializing pygame. You could use something like,

def backgroundmain():
    events = pygame.event.get()                #save events
    spritex = movementsprite(events)           #added events arg
    spritey = movementspritevert(events)       #added events arg
    backdrop = pygame.Rect(0, 0, 640, 640) 
    screen.fill((50,50,50))
    playingfeildwidth = (32, 608)
    playingfeildheight = (32, 608)

    screen.blit(warrior1, (spritex, spritey))

Then, change the movement functions from this:

def movementspritevert():   

    #Do stuff ...

    for event in pygame.event.get():
         if event.type == pygame.QUIT:
             running = False
         elif event.type == pygame.KEYDOWN:

to this:

def movementspritevert(events):   

    #Do stuff ...

    for event in events:
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:

The key is that every time you use event.get(), it will remove the events, so your next call won't get the same events. Basically, if you want one key press to be used by all of your movement functions, then save the events as a variable and pass that to the functions.

Upvotes: 3

Related Questions