Sprite leaves duplicates when I move it
Question:
I have been learning online and used various tutorials to draw a sprite in a pygame window. I am now trying to have it move a set number of pixels across a screen (dependant on the number returned from a diceroll).
def diceroll():
roll = random.randint(1, 6)
print(roll)
playerCar.move_piece_hoz((WIDTH / 13) * roll)
def main():
run = True
clock = pygame.time.Clock()
while run: # a while loop to run the game out of, it sets the clock speed and also consistently checks if
# user ever quits
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.MOUSEBUTTONDOWN:
diceroll()
# checks any updates to the array of sprites
all_sprites_list.update()
# draws all our sprites in their respective positions
all_sprites_list.draw(screen)
# Refresh Screen
pygame.display.flip()
main()
there is the relevant code , I essentially want it so whenever the player presses the left mouse button it calls the dice roll function that will then pick a random number of pieces across a board. However , whenever I press the left mouse button the sprite basically remains in it’s current position and a new duplicate copy is drawn where it should be going. I have attached an image in-case there is any confusion as to what I mean here. The sprite is the red square.
If I call the function manually by using : diceroll() by itself , outside of the main() function. The sprite is redrawn correctly with no issues and without leaving a duplicate , however that way I can only call it once which is not what I need.
Thank you.
Answers:
screen
is a pygame.Surface
object.
When you draw something on a Surface, the pixel data stored in the Surface object is changed. The entire scene is drawn anew in every frame. You need to clear the display or draw the background in every frame:
def main():
run = True
clock = pygame.time.Clock()
while run: # a while loop to run the game out of, it sets the clock speed and also consistently checks if
# user ever quits
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.MOUSEBUTTONDOWN:
diceroll()
screen.fill(0) # <--- this is missing
# checks any updates to the array of sprites
all_sprites_list.update()
# draws all our sprites in their respective positions
all_sprites_list.draw(screen)
# Refresh Screen
pygame.display.flip()
main()
The typical PyGame application loop has to:
- handle the events by calling either
pygame.event.pump()
or pygame.event.get()
.
- update the game states and positions of objects dependent on the input events and time (respectively frames)
- clear the entire display or draw the background
- draw the entire scene (
blit
all the objects)
- update the display by calling either
pygame.display.update()
or pygame.display.flip()
- limit the frames per second to limit CPU usage with
pygame.time.Clock.tick
I have been learning online and used various tutorials to draw a sprite in a pygame window. I am now trying to have it move a set number of pixels across a screen (dependant on the number returned from a diceroll).
def diceroll():
roll = random.randint(1, 6)
print(roll)
playerCar.move_piece_hoz((WIDTH / 13) * roll)
def main():
run = True
clock = pygame.time.Clock()
while run: # a while loop to run the game out of, it sets the clock speed and also consistently checks if
# user ever quits
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.MOUSEBUTTONDOWN:
diceroll()
# checks any updates to the array of sprites
all_sprites_list.update()
# draws all our sprites in their respective positions
all_sprites_list.draw(screen)
# Refresh Screen
pygame.display.flip()
main()
there is the relevant code , I essentially want it so whenever the player presses the left mouse button it calls the dice roll function that will then pick a random number of pieces across a board. However , whenever I press the left mouse button the sprite basically remains in it’s current position and a new duplicate copy is drawn where it should be going. I have attached an image in-case there is any confusion as to what I mean here. The sprite is the red square.
If I call the function manually by using : diceroll() by itself , outside of the main() function. The sprite is redrawn correctly with no issues and without leaving a duplicate , however that way I can only call it once which is not what I need.
Thank you.
screen
is a pygame.Surface
object.
When you draw something on a Surface, the pixel data stored in the Surface object is changed. The entire scene is drawn anew in every frame. You need to clear the display or draw the background in every frame:
def main():
run = True
clock = pygame.time.Clock()
while run: # a while loop to run the game out of, it sets the clock speed and also consistently checks if
# user ever quits
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.MOUSEBUTTONDOWN:
diceroll()
screen.fill(0) # <--- this is missing
# checks any updates to the array of sprites
all_sprites_list.update()
# draws all our sprites in their respective positions
all_sprites_list.draw(screen)
# Refresh Screen
pygame.display.flip()
main()
The typical PyGame application loop has to:
- handle the events by calling either
pygame.event.pump()
orpygame.event.get()
. - update the game states and positions of objects dependent on the input events and time (respectively frames)
- clear the entire display or draw the background
- draw the entire scene (
blit
all the objects) - update the display by calling either
pygame.display.update()
orpygame.display.flip()
- limit the frames per second to limit CPU usage with
pygame.time.Clock.tick