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