Pygame key hold down?

2019-05-30 02:35发布

问题:

Heres the code:

import pygame, sys
from pygame.locals import *

RED   = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE  = (0, 0, 255)
WHITE = (255, 255, 255)
GRASSCOLOR = GREEN
BGCOLOR = WHITE

WINDOWWIDTH = 500
WINDOWHEIGHT = 300

def main():
    pygame.init()

    global DISPLAYSURF

    DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
    pygame.display.set_caption('Platformer')

    player = pygame.image.load('megaman_running_sprites_by_cobalt_blue_knight-d2y1i8s.png')

    playerx = 140
    playery = 10

    DISPLAYSURF.fill(BGCOLOR)
    DISPLAYSURF.blit(player, (10, 140))
    while True: # Event handling loop
        ground()
        mousex, mousey = pygame.mouse.get_pos()

        for event in pygame.event.get():
            if event.type == QUIT:
                terminate()
            elif event.type == KEYDOWN:
                if event.key == K_RIGHT:
                    DISPLAYSURF.fill(BGCOLOR)
                    playery += 10
                    DISPLAYSURF.blit(player, (playery, playerx))

                elif event.key == K_LEFT:
                    DISPLAYSURF.fill(BGCOLOR)
                    playery -= 10
                    DISPLAYSURF.blit(player, (playery, playerx))

                elif event.key == K_SPACE:
                    DISPLAYSURF.fill(BGCOLOR)
                    playerx -= 15
                    DISPLAYSURF.blit(player, (playery, playerx))
                    DISPLAYSURF.fill(BGCOLOR)
                    playerx -= 15
                    DISPLAYSURF.blit(player, (playery, playerx))
                    DISPLAYSURF.fill(BGCOLOR)
                    playerx -= 10
                    DISPLAYSURF.blit(player, (playery, playerx))
                    DISPLAYSURF.fill(BGCOLOR)
                    playerx -= 5
                    DISPLAYSURF.blit(player, (playery, playerx))

            elif event.type == KEYUP:

                if event.key == K_SPACE:
                    pygame.time.wait(100)
                    DISPLAYSURF.fill(BGCOLOR)
                    playerx += 45
                    DISPLAYSURF.blit(player, (playery, playerx))

                elif event.key == K_RIGHT:
                    DISPLAYSURF.fill(BGCOLOR)
                    DISPLAYSURF.blit(player, (playery, playerx))

        pygame.display.update()

def terminate(): # Terminates the program
    pygame.quit()
    sys.exit()

def ground():
    pygame.draw.rect(DISPLAYSURF, GRASSCOLOR, (0, 250, WINDOWWIDTH, 100))

if __name__ == '__main__':
    main()

I have it so, when I press the right/left key the image goes left and right 10 pixels. But how would I make it so when I hold the keys down, it repeats the the function, and if I let the keys go, it would stop. I have tried adding a while loop, all that does is make the guys infinitetly go to the right/left, so is there a pygame module to add this?

回答1:

You don't need another module for that, but another approach and many more corrections are needed here.

First of all: Do ONE blitting run per frame, not one everytime you changed something somewhere.

while True: # Event handling loop
    ground()
    mousex, mousey = pygame.mouse.get_pos()

    for event in pygame.event.get():
        if event.type == QUIT:
               terminate()
        elif event.type == KEYDOWN:
            if event.key == K_RIGHT:
                playery += 10
             elif event.key == K_LEFT:
                playery -= 10
             elif event.key == K_SPACE:
                #WTH are you doing here anyway???

        elif event.type == KEYUP:

            if event.key == K_SPACE:
                pygame.time.wait(100) #What is this doing here?

    DISPLAYSURF.fill(BGCOLOR)
    DISPLAYSURF.blit(player, (playerx, playery))
    pygame.display.update()

Then second: Change the x and y value, it's the wrong way round. x is horizontal, y is vertical. It's always and everywhere like this, if you reinvent the wheel here, people can't read your code anymore.

Now for the problem you asked for:

You need to define a variable, for example "move_left" and "move_right".

in the event check of the loop you then handle them as follow:

if event.type == KEYDOWN:
    if event.key == K_RIGHT:
        move_right = True

if event.type == KEYUP:
    if event.key == K_RIGHT:
        move_right = False

then check somewhere in your loop, whether the move_left or move_right variable is true:

if move_right == True:
    playerx += 10

When we press the key, we trigger the KEYDOWN event which sets the variable to true. If the variable is true, the program will change the player's position (note: 10 pixels per frame might be too much) every frame while this variable is true and it stays true until we trigger the KEYUP event. In other words: while the key is pressed, the variable is true and the player moves. When we release the key, the variable changes to false and the player stops moving.

I didn't give you a ready-to-use code, that's just the explanation of how it's done. If you really can't figure out how to implement is, feel free to ask again.



回答2:

You may use pygame.key.set_repeat() function in order to allow multiple events.



标签: pygame