Search code examples
pythonpygamepygame-surfacepygame-clockpygame-tick

Pygame - Is it possible to change the background image in relation to time?


I'm using pygame in order to create a sort of animation. What I have in mind is to have a series of background images change in relation to the time that has passed once I initiate the game. I came up with this code to do so:

while True:

    DISPLAYSURF.fill(black)  #fills the displaysurf with black

    for time in pygame.time.get_ticks():

            if time == 2:
                img_1 = img_2
                DISPLAYSURF.blit(img_2, (0, 0)) #copy, pastes the surface object to fixed point
            if time == 4:
                img_2 = img_3
                DISPLAYSURF.blit(img_3, (0, 0))
            if time == 8:
                img_3 = img_4
                DISPLAYSURF.blit(img_4, (0, 0))
            if time == 10:
                img_4 = img_5
                DISPLAYSURF.blit(img_5, (0, 0))
            if time == 12:
                img_5 = img_6
                DISPLAYSURF.blit(img_6, (0, 0))
            if time == 14:
                img_6 = img_7
                DISPLAYSURF.blit(img_7, (0, 0))
            if time == 16:
                img_7 = img_8
                DISPLAYSURF.blit(img_8, (0, 0))

    pygame.display.flip()
    clock.tick(FPS)

What I received back when I ran the program was "'int' object is not iterable" which made me think that I may not be able to do what I had in mind, because the images I have are classified in Pygame as surface objects. I'm thinking of two things:

-->Is it possible to create a function that can re-upload the images in relation to time by somehow converting the surface objects' type?

-->Is my code even reflecting what I want it to do?

Please let me know and fire away with the critiques! I'm very new to coding, so any feedback is helpful!


Solution

  • @Aggragoth has covered the error message already, so I wont go into that.

    One way to periodically change the background is to keep a timer, and adjust the background based on a predefined period.

    import pygame
    import time
    
    # Window size
    WINDOW_WIDTH  = 200
    WINDOW_HEIGHT = 200
    
    # background colour
    SKY_BLUE      = (161, 255, 254)
    WHITE         = (255, 255, 255)
    BLUE          = (  5,  55, 255)
    
    ### MAIN
    pygame.init()
    surface_type = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
    window       = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), surface_type )
    pygame.display.set_caption("Background Change")
    
    # Variables to manage the background change
    background_delay = 1500  # milliseconds
    background_time  = 0     # when the background last changed
    backgrounds      = [ WHITE, SKY_BLUE, WHITE, SKY_BLUE, BLUE ]
    background_index = 0     # index of the currently used background
    
    # Main loop
    clock = pygame.time.Clock()
    done = False
    while not done:
    
        # Handle user-input
        for event in pygame.event.get():
            if ( event.type == pygame.QUIT ):
                done = True
    
        # Re-draw the screen background from the list after a delay
        time_now = pygame.time.get_ticks()
        if ( time_now > background_time + background_delay ):
            # switch to the next background
            background_time = time_now
            background_index += 1
            # if we're out of backgrounds, start back at the head of the list
            if ( background_index >= len( backgrounds ) ):
                background_index = 0
    
        # Draw the background
        window.fill( backgrounds[ background_index ] )
    
        pygame.display.flip()
        # Update the window, but not more than 60fps
        clock.tick_busy_loop( 60 )
    
    pygame.quit()
    

    The main part of the code is to keep the time we last changed the background. If the elapsed time since then (from pygame.time.get_ticks()) is greater than the last-change-time plus a delay, then change to the next background.

    In this example I've just used colours, but the backgrounds[] list could also hold images, and be used with window.blit().