3

I've been trying to make a game but I can't get the animation to work. When I launch the game it loads all of the images on top of itself and it 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 doesnt animate it just loads all the images on top of eachother please help me. thanks.

1 Answer 1

3

Yes, your for img in img_names: loop just blits all images. My recommendation would be to store the images/pygame.Surfaces in a list and then use an index variable that keeps track of the current image.

So roughly:

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)

Note that this example is frame rate bound and I'd recommend to increment the index after some time interval instead.

Addendum: To slow the animation down, you can for example count the frames and increment the index only if the frame_count is 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 that would still be frame rate bound.

The right way to do it, is to use a timer variable and to add the time that clock.tick returns to it, and if the timer is above some arbitrary threshold, increment the index and change 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
Sign up to request clarification or add additional context in comments.

9 Comments

I can show you a frame rate independent version as well if you want.
when i lauch i get this error: UnboundLocalError: local variable 'index' referenced before assignment
That means you haven't defined the variable index in your function.
i still get this error: TypeError: argument 1 must be pygame.Surface, not str do you want me to update my code?
The images in the list have to be pygame.Surfaces not strings, so the loaded images.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.