user8071203
user8071203

Reputation:

Pygame player movement stops when too many keys are pressed at the same time

When I try to move my character and press any other key at the same time, the movement suddenly stops. For example, the space key in my code is used to shoot a tiny orb out of the spaceship. Every time I press space and I am moving left and right quickly, the orb will shoot out but the player movement will be frozen for a second or two.

I have tried to switch to different ways of handling the way keys are input, but all of them seem to lead to this same problem. pygame.key.get_pressed() also has this problem when in my code.

I am not quite sure if this is a problem with my laptop keyboard or something in the code, so the code for the entire file is below.

import pygame, sys, decimal

# Screen Size
SCREEN_X = 400
SCREEN_Y = 400

# Loading Images
backgroundImg = pygame.image.load('StarBackground.png')
menuBar = pygame.image.load('Menu_Bar.png')
shipImg = pygame.image.load('PowerShip.png')
orb = pygame.image.load('Orb00.png')

class Ship(pygame.sprite.Sprite):
    # Movement rate of change
    change_x = 0

    # Methods
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        self.image = shipImg.convert_alpha()

        self.rect = self.image.get_rect()

        self.rect.x = SCREEN_X / 2 - 8
        self.rect.y = SCREEN_Y - 40

    def move(self, speed):
        self.change_x = speed

    def stop(self):
        self.change_x = 0


    def update(self, screen):
        self.rect.x += self.change_x

        if self.rect.x < 0:
            self.rect.x = 0
        elif self.rect.right > SCREEN_X:
            self.rect.x -= 1

        screen.blit(self.image, self.rect)

class MenuBar(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        self.image = menuBar.convert_alpha()

        self.rect = self.image.get_rect()

        self.rect.x = 10
        self.rect.y = 0

    def update(self, screen):

        screen.blit(self.image,self.rect)

class Bullet1(pygame.sprite.Sprite):

    def __init__(self,x,y):
        pygame.sprite.Sprite.__init__(self)

        self.image = orb.convert_alpha()
        self.rect = self.image.get_rect()

        self.rect.x = x
        self.rect.y = y
        self.alive = True

    def update(self):
        if self.alive == True:
            self.rect.y -= 1

        if self.alive == False:
            self.rect.y = -10000

class HealthBar(pygame.sprite.Sprite):
    pass

class EnergyBar(pygame.sprite.Sprite):
    pass

class PointsBar(pygame.sprite.Sprite):
    pass

class Background(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        self.image = backgroundImg.convert_alpha()

        self.rect = self.image.get_rect()

        self.rect.x = 0
        self.rect.y = 0

    def update(self, screen):
        if self.rect.top > 0:
            self.rect.y = SCREEN_Y * -1

        self.rect.y += 1

        screen.blit(self.image, self.rect)

def main():
    pygame.init()

    size = [SCREEN_X, SCREEN_Y]
    screen = pygame.display.set_mode(size, pygame.DOUBLEBUF)    # Set the height and width of the screen

    pygame.display.set_caption("Space Adventure")               # Setting the game name in the title bar

    background = Background()       # Creating the game objects
    menubar = MenuBar()
    ship = Ship()
    finished = False                # Close button exit code

    bullet1Enabled = True
    bullet1Count = 1
    spacePressed = False

    clock = pygame.time.Clock()     # Manages the frames per second

    lastkey = None                  # Variable that stores the last key pressed

    bulletlist = []

    # Game loop
    while not finished:
        for event in pygame.event.get():
            print(lastkey)
            if event.type == pygame.QUIT:
                finished = True

            pygame.event.set_blocked(pygame.MOUSEMOTION)

            if event.type == pygame.KEYDOWN:

                if lastkey != pygame.K_SPACE:
                    lastkey = event.key


                if event.key == pygame.K_SPACE:
                    spacePressed = True
                    if bullet1Enabled == True:
                        bullet1 = Bullet1(ship.rect.x, ship.rect.y)
                        bulletlist.append(bullet1)
                        bullet1Count = 1
                else:
                    spacePressed = False

            if event.type == pygame.KEYUP:

                if event.key == pygame.K_RIGHT and lastkey != pygame.K_LEFT:
                    lastkey = None
                    ship.move(0)
                if event.key == pygame.K_LEFT and lastkey != pygame.K_RIGHT:
                    lastkey = None
                    ship.move(0)

                if event.key == pygame.K_RIGHT or lastkey == pygame.K_LEFT:
                    spacePressed = False

                if event.key == pygame.K_LEFT or lastkey == pygame.K_RIGHT:
                    spacePressed = False

            #Bullet Delay

            if spacePressed == True:
                 bullet1Count = True
            if spacePressed == False:
                bullet1Count =  False

            if lastkey == pygame.K_RIGHT:
                ship.move(1)
            if lastkey == pygame.K_LEFT:
                ship.move(-1)

        clock.tick(240)             # Frames per second

        background.update(screen)   # Background update
       # Menu Bar update
        ship.update(screen)         # Ship update

        for b in bulletlist:
            if b.rect.bottom <= 0:
                b.alive = False

            b.update()

            screen.blit(b.image, b.rect)

        menubar.update(screen)

        pygame.display.flip()       # Updates the display for everything

    pygame.quit() # Clean shutdown on IDLE

if __name__ == "__main__":
    main()

Upvotes: 1

Views: 726

Answers (1)

skrx
skrx

Reputation: 20468

The problem occurs because you don't reset lastkey to None after you release the space bar, so you have to press left or right twice.

if event.type == pygame.KEYUP:
    if event.key == pygame.K_SPACE:
        lastkey = None

I don't see why you need the lastkey variable at all. I'd remove these lines from the main loop,

if lastkey == pygame.K_RIGHT:
    ship.move(1)
if lastkey == pygame.K_LEFT:
    ship.move(-1)

insert them in the event loop and change lastkey to event.key:

if event.type == pygame.KEYDOWN:
    if event.key == pygame.K_RIGHT:
        ship.move(1)
    if event.key == pygame.K_LEFT:
        ship.move(-1)

Now you should be able to remove the lastkey completely.

Upvotes: 2

Related Questions