Creating Python animations with Pygame
I tried to create a game, but I cannot get the animation to work. When I start the game, it loads all images on top of itself and doesn't animate. Here's my code:
import pygame
import os
pygame.init()
width = 800
height = 600
ship_width = 56
ship_height = 64
disp = pygame.display.set_mode((width,height))
pygame.display.set_caption("space_game")
clock = pygame.time.Clock()
background = pygame.image.load(os.path.join("Backgrounds", "Space.png"))
img_names = ["sprite_00.png", "sprite_01.png", "sprite_02.png", "sprite_03.png", "sprite_04.png", "sprite_05.png", "sprite_06.png", "sprite_07.png", "sprite_08.png", "sprite_09.png"] #i load all the images here
all_imgs = {}
for img in img_names:
all_imgs[img] = pygame.image.load(img)
def gameLoop():
x = (width * 0.45)
y = (height * 0.8)
x_ch = 0
y_ch = 0
x_bg = 0
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == ord("a"):
x_ch = -5
elif event.key == ord("d"):
x_ch = 5
elif event.key == ord("w"):
y_ch = -5
elif event.key == ord("s"):
y_ch = 5
if event.type == pygame.KEYUP:
if event.key == ord("a") or event.key == ord("d"):
x_ch = 0
if event.key == ord("w") or event.key == ord("s"):
y_ch = 0
x += x_ch
y += y_ch
if x > width - ship_width or x < 0:
x_ch = 0
if y > height - ship_height or y < 0:
y_ch = 0
x_loop = x_bg % background.get_rect().height
disp.blit(background, (0, x_loop - background.get_rect().height))
if x_loop < height:
disp.blit(background, (0, x_loop))
x_bg += 5
for img in img_names:
disp.blit(all_imgs[img], (x, y)) #but this part doesnt work it blits
#all the images on top of eachother
pygame.display.update()
clock.tick(60)
gameLoop()
pygame.quit()
quit()
For some reason, it doesn't animate, it just loads all images on top of each other, please help me. thank.
source to share
Yes, your loop for img in img_names:
just dumps all images. My recommendation was to keep the images /pygame.Surfaces in a list and then use a variable index
that keeps track of the current image.
So rude:
images = [image1, image2, etc.]
index = 0
while True:
index += 1
# Modulo to keep the index in the correct range.
index %= len(images)
current_image = images[index]
disp.blit(current_image, position)
Please note that this example is related to frame rate and I recommend increasing it index
over a period of time.
Addendum: To slow down the animation, you can, for example, count the frames and increase the index only if it is frame_count
greater than 3.
images = [image1, image2, etc.]
index = 0
frame_count = 0
while True:
frame_count += 1
if frame_count > 3:
frame_count = 0
index += 1
index %= len(images)
current_image = images[index]
disp.blit(current_image, position)
But it will still be related to the frame rate.
The correct way to use it is to use a variable timer
and add the time returned by it clock.tick
, and if the timer is above some arbitrary threshold, increase the index and resize the image.
images = [image1, image2, etc.]
index = 0
current_image = images[index]
timer = 0
dt = 0
while True:
timer += dt
# If 1 second has passed.
if timer > 1:
timer = 0
index += 1
index %= len(images)
current_image = images[index]
screen.blit(current_image, position)
# dt is the time that has passed since the last clock.tick call.
# Divide by 1000 to convert milliseconds to seconds.
dt = clock.tick(FPS) / 1000
source to share