'Pygame waits for key to be held

I am working on a basic game with pygame, im not the biggest fan of python so i decided to make myself like it.

Now, for the issue. When i am checking for keypresses, i want the player to continue moving when i hold the key. When i press right arrow, it moves once, then waits a second then continues. Im not sure how to describe it. It is how DAS works in tetris.

Here is the code, i wont post all of it but i will post all the important things

player.py

import pygame
from settings import *
from tileset import TileSet
class Player(pygame.sprite.Sprite):
    def __init__(self, pos, group):
        super().__init__(group)
        self.image = TileSet('Assets/Actor/Characters/Princess/SpriteSheet.png', 16, 16).get(0,0)
        self.SCALE_FACTOR = 4
        self.size = self.image.get_size()
        self.image = pygame.transform.scale(self.image, (int(self.size[0] * self.SCALE_FACTOR), int(self.size[0] * self.SCALE_FACTOR)))
        self.rect = self.image.get_rect(topleft = pos)

        self.direction = pygame.math.Vector2()
        self.speed = 10
    def input(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_w]:
            self.direction.y = -1
        elif keys[pygame.K_s]:
            self.direction.y =  1
        else:
            self.direction.y =  0
        if keys[pygame.K_d]:
            self.direction.x =  1
        elif keys[pygame.K_a]:
            self.direction.x = -1
        else:
            self.direction.x =  0
    def move(self, speed):
        self.rect.center += self.direction * speed
    def update(self):
        self.input()
        self.move(self.speed)

level.py

import pygame
from settings import *
from tile import Tile
from player import Player
from debug import debug
class Level:
    def __init__(self):
        self.dsurf = pygame.display.get_surface()
        self.visible_sprites = pygame.sprite.Group()
        self.obstacle_sprites = pygame.sprite.Group()

        self.create_map()
    def create_map(self):
        for row_i, row in enumerate(WORLD_MAP):
            for col_i, col in enumerate(row):
                x = col_i * TILE_SIZE
                y = row_i * TILE_SIZE
                if col == 'x':
                    Tile((x, y), [self.visible_sprites, self.obstacle_sprites])
                if col == 'p':
                    self.player = Player((x, y), [self.visible_sprites])
    def tick(self):
        self.visible_sprites.draw(self.dsurf)
        self.visible_sprites.update()
        debug(f"Player direction: {self.player.direction}")

main.py

import pygame
import pygame.locals
import sys

from settings import *
from level import Level
class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
        pygame.display.set_caption("Darka")
        self.clock = pygame.time.Clock()
        self.level = Level()
    def run(self):
        while pygame.event.wait().type != pygame.locals.QUIT:
            self.screen.fill('black')
            self.level.tick()
            pygame.display.update()
            self.clock.tick(FPS_CAP)

if __name__ == "__main__":
    game = Game()
    game.run()


Solution 1:[1]

I would change your main loop to relay events to the player sprite and call its update function

def run(self):
    finished = False
    while not finished:
            for event in pygame.event.get():            
                if event.type == pygame.QUIT:
                    finished = True
                elif event.type in (pygame.KEYDOWN, pygame.KEYUP):
                    #send all keys to player sprite
                    self.level.player.move(event)

            self.screen.fill('black')
            self.level.player.move()  # or add to level.tick()
            self.level.tick()
            pygame.display.update()
            self.clock.tick(FPS_CAP)
        

Changes to Player sprite input() function

def input(self, event):
    if event.type == pygame.KEYDOWN
        if event_key == pygame.K_w:
            self.direction.y = -1
        elif event_key ==pygame.K_s:
            self.direction.y =  1
        elif event_key == pygame.K_d:
            self.direction.x =  1
        elif event_key == pygame.K_a]:
            self.direction.x = -1
    elif event.type == pygame.KEYUP:
        if event_key in (pygame.K_w, pygame.K_s):
            self.direction.y =  0
        elif event_key in (pygame.K_d, pygame.K_a):
            self.direction.x =  0

This way your sprite should start moving when you press a direction key and stop on release.

Note: untested code.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 import random