Home > Software engineering >  Pygame Animated background freezing
Pygame Animated background freezing

Time:07-16

I was working on making a animated background for my game. So I have the frames for it there are 174 ans store them in a list in a class. when I run the animate function in the class it only displays one image then dosnt do anything. I figured it is because of the for loop that is putting the images on the screen. How can I improve this so it can work properly?

basePath = os.path.dirname(sys.argv[0]) "\\"
pygame.init()
#setting fps lock for game and startign clock (Both are needed for fps)
fps = 30
fClock = pygame.time.Clock()
#Setting up pygame display size and window
res = pygame.display.Info()
tv = pygame.display.set_mode((res.current_w, res.current_h), pygame.SCALED)

class Background:
    def __init__(self):
        self.imFrames = os.listdir(basePath "Background Frames/")
        self.nTime = 0

    def animate(self):
        index = 0
        tNow = pygame.time.get_ticks()
        if (tNow > self.nTime):
            fDelay = 0.1
            self.nTime = tNow   fDelay

            index  = 1
            if index >= len(self.imFrames):
                index = 0
                
        for item in self.imFrames:
            tv.blit(pygame.image.load(basePath "Background Frames/" item).convert_alpha(), (0,0))
back = Background()
go = True
while go:
    #event checks
    for event in pygame.event.get():
        if event.type == QUIT:
            go = False
        elif event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                go = False

    back.animate()
    pygame.display.update()
    fClock.tick(fps)
#Closing pygame and closing all functions
pygame.quit()
sys.exit()

CodePudding user response:

Never implement a loop that tires to animate something in the application loop. This stops the application loop and the game becomes unresponsive. You need to load all the image int the constructor and loop through the images while the application loop is running.
Beside that, pygame.image.load is a very expensive operation. It needs to read this image file from the device and decode the image file. Never call pygame.image.load when the application loop is running, always load the images before the application for good performance.
Further note that pygame.time.get_ticks() returns the time in milliseconds, not seconds. 0.1 seconds is 100 milliseconds.

class Background:
    def __init__(self):
        self.imFrames = os.listdir(basePath "Background Frames/")
        
        self.images = []
        for item in self.imFrames:
            image = pygame.image.load(basePath "Background Frames/" item).convert_alpha()
            self.images.appned(image)

        self.image = self.images[0]
        self.nTime = pygame.time.get_ticks()
        self.index = 0

    def animate(self):
        tNow = pygame.time.get_ticks()
        if tNow > self.nTime:
            fDelay = 100
            self.nTime = tNow   fDelay

            self.index  = 1
            if self.index >= len(self.images):
                self.index = 0
            self.image = self.images[self.index]
                
        tv.blit(self.image, (0,0))

CodePudding user response:

You need to make a python list of all the images (a for-loop that appends pygame.image.load(basePath "Background Frames"/item).convert_alpha() to the list would suffice), which is what I had mistakenly thought self.ImFrames was and instead of making a for-loop to run the animations, utilize the game-loop to your advantage and have the function which draws, increment the value every iteration of the game-loop (or you could do it externally which is how I did it):

def animate(self, index): # new param to avoid using global
        tNow = pygame.time.get_ticks()
        if (tNow > self.nTime):
            fDelay = 0.1
            self.nTime = tNow   fDelay

            if index >= len(self.images):
                index = 0
        tv.blit(self.images[index])
index = 0
while go:
    # code
    # if animating, do this
    index  = 1
    # code
  • Related