[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] One key press many events



I want player to move continuously when arrow or wsad key is pressed. When I press arrow or wsad for longer time only one key event is registered. I don't understand why and how to change it.
processInput is where it takes place.

import sys
import pygame
from pygame.math import Vector2
from pygame.locals import *
from enum import Enum


class Color(Enum):
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
WHITE = (255, 255, 255)


class GameObject:
def __init__(self, state, rect, color):
self.rect = rect
self.color = color
self.state = state
self.state.game_objects.append(self)


class Player(GameObject):
def __init__(self, state):
player_rect = pygame.Rect(300, 100, 50, 50)
player_color = Color.BLACK
super().__init__(state, player_rect, player_color)

def move(self, left, top):
self.rect.left = left
self.rect.top = top


class GameState:
def __init__(self):
self.game_objects = []
self.player = Player(self)
self.MOVESPEED = 6

class Command():
def run(self):
raise NotImplementedError()
class MovePlayer(Command):
"""
This command moves a unit in a given direction
"""
def __init__(self, move_left, move_right, move_up, move_down, state):
self.move_left = move_left
self.move_right = move_right
self.move_up = move_up
self.move_down = move_down
self.state = state
def run(self):
if self.move_down and self.state.player.rect.bottom < UserInterface.WINDOWHEIGHT:
self.state.player.rect.top += self.state.MOVESPEED
if self.move_up and self.state.player.rect.top > 0:
self.state.player.rect.top -= self.state.MOVESPEED
if self.move_left and self.state.player.rect.left > 0:
self.state.player.rect.left -= self.state.MOVESPEED
if self.move_right and self.state.player.rect.right < UserInterface.WINDOWWIDTH:
self.state.player.rect.left += self.state.MOVESPEED

class UserInterface:
WINDOWWIDTH = 400
WINDOWHEIGHT = 400
def __init__(self):
pygame.init()
self.windowSurface = pygame.display.set_mode(
(UserInterface.WINDOWWIDTH, UserInterface.WINDOWHEIGHT), 0, 32)

self.gamestate = GameState()
pygame.display.set_caption('Collision detection')
self.mainClock = pygame.time.Clock()
self.commands = []

def processInput(self):
move_left = move_right = move_up = move_down = False
for event in pygame.event.get():
print("event type: ",pygame.event.event_name(event.type))
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
#Change the keyboard variables
if event.key == K_LEFT or event.key == K_a:
move_right = False
move_left = True
if event.key == K_RIGHT or event.key == K_d:
move_right = True
move_left = False
if event.key == K_UP or event.key == K_w:
move_up = True
move_down = False
if event.key == K_DOWN or event.key == K_s:
move_up = False
move_down = True
if event.type == KEYUP:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if event.key == K_LEFT or event.key == K_a:
move_left = False
if event.key == K_RIGHT or event.key == K_d:
move_right = False
if event.key == K_UP or event.key == K_w:
move_up = False
if event.key == K_DOWN or event.key == K_s:
move_down = False
if event.key == K_x:
player.top = random.randint(0, WINDOWHEIGHT)
player.left = random.randint(0, WINDOWWIDTH)
if move_left or move_right or move_up or move_down:
self.commands.append(
MovePlayer(move_left, move_right, move_up, move_down, self.gamestate)
)
def update(self):
for command in self.commands:
command.run()
self.commands.clear()

def render(self):
self.windowSurface.fill(Color.WHITE.value)
for game_object in self.gamestate.game_objects:
pygame.draw.rect(
self.windowSurface, game_object.color.value, game_object.rect)
pygame.display.update()

def run(self):
while True:
self.processInput()
self.update()
self.render()
self.mainClock.tick(40)


user_interface = UserInterface()
user_interface.run()