pygame key.set_repeat not working

2019-07-22 13:40发布

问题:

I am new to pygame and I am trying to make pong in order to learn it. I am trying to make smooth controls so that holding down an arrow will work, but it is not working right now.

import sys, pygame
pygame.init()
size = (500, 350)
screen = pygame.display.set_mode(size)
x = 1
xwid = 75
yhei = 5
pygame.key.set_repeat(0, 500)
while True:
    vector = 0
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                vector = 4
            elif event.key == pygame.K_LEFT:
                vector = -4
    pygame.draw.rect(screen,(255,255,255),(x,size[1] - yhei,xwid,yhei),0)
    pygame.display.update()
    screen.fill((0,0,0))
    x += vector
    if x <= 0:
        x = 0
    elif x >= size[0] - xwid:
        x = size[0] - xwid

why does this not work for holding down the left or right arrows?

回答1:

pygame.key.set_repeat(0, 500)

If you set the delay parameter to 0, key repeat will be disabled. The documentation isn't quite clear about that:

pygame.key.set_repeat()
control how held keys are repeated
set_repeat() -> None
set_repeat(delay, interval) -> None

When the keyboard repeat is enabled, keys that are held down will generate multiple pygame.KEYDOWN events. The delay is the number of milliseconds before the first repeated pygame.KEYDOWN will be sent. After that another pygame.KEYDOWN will be sent every interval milliseconds. If no arguments are passed the key repeat is disabled.

When pygame is initialized the key repeat is disabled.

Emphasis mine.

You could set the delay to 1, and it would work as expected:

pygame.key.set_repeat(1, 10) # use 10 as interval to speed things up.

But note that you should not use set_repeat and the pygame.KEYDOWN event to implement movement. If you do, you won't be able to observe real single key strokes, since if the player presses a key, a whole bunch of pygame.KEYDOWN events would be created.

Better use pygame.key.get_pressed(). Have a look at his minimal example:

import pygame
pygame.init()
screen = pygame.display.set_mode((680, 460))
clock = pygame.time.Clock()

# use a rect since it will greatly 
# simplify movement and drawing
paddle = pygame.Rect((0, 0, 20, 80))

while True:

    if pygame.event.get(pygame.QUIT): break
    pygame.event.pump()

    # move up/down by checking for pressed keys
    # and moving the paddle rect in-place
    keys = pygame.key.get_pressed()
    if keys[pygame.K_UP]: paddle.move_ip(0, -7)
    if keys[pygame.K_DOWN]: paddle.move_ip(0, 7)

    # ensure the paddle rect does not go out of screen
    paddle.clamp_ip(screen.get_rect())

    screen.fill((0,0,0))    
    pygame.draw.rect(screen, (255,255,255), paddle)
    pygame.display.flip()

    clock.tick(60)


回答2:

I know what do you mean. Try this:

import sys, pygame
from pygame.locals import *

pygame.init()
size = (500, 350)
screen = pygame.display.set_mode(size)
x = 1
xwid = 75
yhei = 5

clock = pygame.time.Clock()
while True:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    key_pressed = pygame.key.get_pressed()
    if key_pressed[K_LEFT]:
        x -= 4
        if x <= 0:
            x = 0
    if key_pressed[K_RIGHT]:
        x += 4
        if x >= size[0] - xwid:
            x = size[0] - xwid

    pygame.draw.rect(screen,(255,255,255),(x,size[1] - yhei,xwid,yhei),0)
    pygame.display.update()
    screen.fill((0,0,0))


标签: python pygame