Using PyGame, I want to create a moving square which moves in a grid, controlled by keyboard presses of the arrows. So, pressing the "up" key moves the square to the cell directly upwards, pressing the "right" key moves the square to the cell directly to the right, etc.

In my loop, I use pygame.time.wait(x), to pause for x ms. However, choosing the correct value for x is proving difficult. If x is too large (e.g. 1000), then the square does not respond immediately, and I actually have to hold down the key to get it to move. But if x is too small (e.g. 10), then the square will move several times in a row whenever I press a key. But I just want the square to move once for every key press. How can I do this? Thanks!

Below is the important part of my code:

    x = 100
    current_pos = [0, 0]

    while True:

        pygame.event.pump()  # process event queue
        is_key_pressed = pygame.key.get_pressed()

        if is_key_pressed[pygame.K_UP]:
            current_pos[1] -= 1

        elif is_key_pressed[pygame.K_RIGHT]:
            current_pos[0] += 1

        elif is_key_pressed[pygame.K_DOWN]:
            current_pos[1] += 1

        elif is_key_pressed[pygame.K_LEFT]:
            current_pos[0] -= 1



1 Answer 1


Use an event loop to move the object a given distance per key press. Also, to limit the frame rate you should instantiate a pygame.time.Clock and call its tick method. pygame.time.wait makes your program unresponsive for the passed time interval.

import sys
import pygame as pg

def main():
    screen = pg.display.set_mode((640, 480))
    # Instantiate a Clock to control the frame rate.
    clock = pg.time.Clock()
    player_rect = pg.Rect(0, 380, 90, 90)

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_RIGHT:
                    player_rect.x += 100
                if event.key == pg.K_UP:
                    player_rect.y -= 100

        screen.fill((60, 60, 60))
        pg.draw.rect(screen, (120, 190, 90), player_rect)
        clock.tick(30)  # Limit the frame rate to 30 fps.

if __name__ == '__main__':

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .