Reputation: 29
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
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
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