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.

+3


source to share


1 answer


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

      

+3


source







All Articles