Search code examples
python-3.xpygamekeypress

Python 3 : When I keep a key pressed down and press then release another, pygame don't take new events


I have a script that make a 'character' move across a map, but when I hold a direction, then hit (press then release) another key, the 'for event in pygame.event_get()' loop don't work anymore I do have a 'pygame.key.set_repeat()' and I've tried to change the value of 'event' upon each key release but I don't know what to do. Here's the script :

import math
import numpy as np
import random as rdm
import pygame
from pygame.locals import *

#functions :

def printScreen():
    global delta
    global Map
    global player
    
    x = (w-player.w)//2
    xMap = x - player.x


    
    y = (h-player.w)//2
    yMap = player.w + y - Map.h + player.y


    fenetre.fill((0, 0, 0))
    fenetre.blit(Map.layer1, (xMap, yMap))
    fenetre.blit(player.image, (x, y))
    pygame.display.flip()

#variables :

h, w = 600, 700
delta = 1 #size of a pixel
run = True
moving = False

#constants :

zeros = tuple([0 for i in range(323)])
directions = ['up', 'down', 'right', 'left']

#pygame initialisation :


pygame.init()
clock = pygame.time.Clock()
fenetre = pygame.display.set_mode((w*delta, h*delta))
pygame.key.set_repeat(40, 40)

#classes :

class player :
    def __init__(self, save) :
        File = open(save + '\savedata.txt')
        Text = File.read()
        File.close
        noLine = 1
        nbCharacters = 0
        lineStart = 0
        for i in range(len(Text)) :
            if Text[i] == '\n' :
                line = Text[lineStart:i]
                lineStart = i+1
                if noLine == 1 :
                    nickName = line
                if noLine == 2 :
                    x = int(line)
                if noLine == 3 :
                    y = int(line)
                noLine += 1
        self.image = pygame.image.load(save + '\player.png')
        self.w = self.image.get_width()
        self.h = self.image.get_height()
        self.nickName = nickName
        self.x = x
        self.y = y
        self.direction = 'down'

player = player("data\player\save01")

class backGround :
    def __init__(self, directory) :
        self.layer1 = pygame.image.load(directory)
        self.w = self.layer1.get_width()
        self.h = self.layer1.get_height()

Map = backGround("data"+"\\"+"town.png")

#images :

#main pygame loop :
        
while run :
    clock.tick(120)
    for event in pygame.event.get() :
        if event.type == QUIT :
            run = False

        if event.type == KEYUP :
            event = 0
            
        keys = pygame.key.get_pressed()
        arrows = keys[273 : 277]
        for i in range(4) :
            if player.direction == directions[i] and arrows[i] == 0 :
                moving = False
            

        if keys == zeros :
            moving = False
            
        if keys[pygame.K_UP] :
            player.y += player.w
            if not moving :
                player.direction = 'up'
            moving = True

        if keys[pygame.K_DOWN] :
            player.y -= player.w
            if not moving :
                player.direction = 'down'
            moving = True

        if keys[pygame.K_RIGHT] :
            player.x += player.w
            if not moving :
                player.direction = 'right'
            moving = True

        if keys[pygame.K_LEFT] :
            player.x -= player.w
            if not moving :
                player.direction = 'left'
            moving = True

        print(player.direction, keys[273 : 277])
    printScreen()
    
pygame.quit()

arrows = keys[273 : 277] refers to the part of the pygame.key.get_pressed() that contain the arrow keys.


Solution

  • The issue is that you are only checking the key array if a new event occurs. You want to check the key array at every loop. You just need to adjust your indents.

    Here is the updated code:

    while run :
        clock.tick(10)
        for event in pygame.event.get() :  # check for new event
            if event.type == QUIT :
                run = False
    
            if event.type == KEYUP :
                event = 0
                
        keys = pygame.key.get_pressed()  # always check this
        arrows = keys[273 : 277]
        for i in range(4) :
            if player.direction == directions[i] and arrows[i] == 0 :
                moving = False
            
        if keys[pygame.K_SPACE] : print('--------------------- space')
    
        if keys == zeros :
            moving = False
            
        .............
        
    pygame.quit()