Petar Grgić
Petar Grgić

Reputation: 29

Pygame image not moving when keys are pressed

The update section of Player class doesn't work when I run the program. It displays the picture, but I can't get it to move right or left when the keys are pressed. It stays motionless. What am I missing?

import pygame
import random
import os

pygame.init()
pygame.mixer.init()

display_width = 460
display_height = 600
FPS = 30

#colors
white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)

game_display = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("Test")
clock = pygame.time.Clock()

img_dir = os.path.join(os.path.dirname(__file__), 'img')

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(player_img, (40,60))
        self.image.set_colorkey(black)
        self.rect = self.image.get_rect()
        self.rect.centerx = display_width/2
        self.rect.bottom = display_height - 10
        self.speedx = 0

    def update(self):
        self.speedx = 0
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_a or event.key == pygame.K_LEFT:
                    self.speedx = -7
                if event.key == pygame.K_d or event.key == pygame.K_RIGHT:
                    self.speedx = 7
                    self.rect.x += self.speedx



#image loading
player_img = pygame.image.load(os.path.join(img_dir, "malirozi.png")).convert()

all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)

#game loop
running = True
while running:
    #Events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    #Logic
    all_sprites.update()

    #Draw / render
    game_display.fill(black)
    all_sprites.draw(game_display)
    #after drawing everything, flip the display
    pygame.display.flip()
    clock.tick(FPS)

pygame.quit()
quit()

Upvotes: 2

Views: 328

Answers (2)

jsbueno
jsbueno

Reputation: 110228

The call to pygame.event.get consumes all events in the queue. That means that it should be done ina single place - when you do for event in pygame.event.get(): in the main boyd, just bellow the while loop, you swallow all keydown events that might be read inside your update method.

The remedy to this is to ensure you make your calls to pygame.event.get in just a single point in your code. You can, for example, append the unhandled events to a list, and pass that list as a parameter to your update method - there you check these events instead of calling pygame.event.get again.

Also, note that the line self.rect.x += self.speedx should be outside the if statement.

...
class Player(pygame.sprite.Sprite):
    def __init__(self):
       ...
       self.events = []
    def update(self):
        self.speedx = 0
        for event in self.events:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_a or event.key == pygame.K_LEFT:
                    self.speedx = -7
                if event.key == pygame.K_d or event.key == pygame.K_RIGHT:
                    self.speedx = 7
        self.rect.x += self.speedx
...
while running:
    #Events
    events = []
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        else:
            events.append(event)
    player.events = events
    #Logic
    all_sprites.update()
...
pygame.quit()
quit()

Upvotes: 2

MANA624
MANA624

Reputation: 1028

Your problem is that your event handling is in two different places, and pygame can only run one event handler at a time. I assume from your code that you only want your guy to move 7 pixels once each time is pressed. If you want him to keep moving, you'll need to add more

import pygame
import random
import os

pygame.init()
pygame.mixer.init()

display_width = 460
display_height = 600
FPS = 30

#colors
white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)

game_display = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("Test")
clock = pygame.time.Clock()

img_dir = os.path.join(os.path.dirname(__file__), 'img')

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(player_img, (40,60))
        self.image.set_colorkey(black)
        self.rect = self.image.get_rect()
        self.rect.centerx = display_width/2
        self.rect.bottom = display_height - 10
        self.speedx = 0


#image loading
player_img = pygame.image.load("guy.png").convert()

all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)

#game loop
running = True
while running:
    #Events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a or event.key == pygame.K_LEFT:
                player.speedx = -7
            if event.key == pygame.K_d or event.key == pygame.K_RIGHT:
                player.speedx = 7
        player.rect.x += player.speedx
    #Logic
    all_sprites.update()
    player.rect.centerx += player.speedx
    print(player.speedx)

    #Draw / render
    game_display.fill(black)
    all_sprites.draw(game_display)
    #after drawing everything, flip the display
    pygame.display.flip()
    clock.tick(FPS)

pygame.quit()
quit()

Upvotes: 0

Related Questions