   Pygame Image Caching slowdown issue
  Hi there,I'm new here, and somewhat of a noob to boot, so bear with me.Anyway, I have been working on a strategy game and have hit a snag with trying to optimize loading of graphics files for the game by only loading each image only once, not each time a sprite class is instantiated that uses the same image as others.  So after making several different attempts, and going through a number of google searches I am at a loss.My problem is not that I cannot load the needed files only once each, the problem comes when I run the program with the code that loads the images only once, it gets massive FPS slowdowns, something like 10 FPS.  Strangely enough when the program uses code which loads the image files each time a sprite is instantiated, it runs just fine.  I have come here with this problem, because in my journeys, I have come across a thread in this very forum with deals with the issue of caching image files.  the thread is here:  http://www.gamedev.net/community/forums/topic.asp?topic_id=554090I even used the exact same cache class in my program, yet I still get major FPS slowdowns as a result.here is an example of the cache class:class ImageCache:    def __init__(self):   self.images = {}    def getImage(self, filename):   if not self.images.has_key(filename):  self.images[filename] = pygame.image.load(filename)   return self.images[filename] and here is the code for the terrain tile class:#define the class for the terrain tileclass Hex_Tile(pygame.sprite.Sprite):    def __init__(self, EX, WY, pic):   #initialize the sprite operator   pygame.sprite.Sprite.__init__(self)   #load the desired image file   self.image = pic   self.rect = self.image.get_rect()   #create a surface for the tile to go on   screen = pygame.display.get_surface()   self.area = screen.get_rect()   self.rect.center = X_Pos, Y_Pos   #these set the grid coordinates of each tile which are assigned to each   #instance as it is created by the map creation loop   self.gridx = EX   self.gridy = WY and here is the code used to place the tile instances, it just randomly chooses which kind of tile it is for each instance, the difference is only cosmetic so far, right above the loop is the creation of an instance of the cache, and the act of caching of the three needed image files:cache = ImageCache()Img1 = cache.getImage('data/hexterrain1.png')Img2 = cache.getImage('data/hexterrain2.png')Img3 = cache.getImage('data/hexterrain3.png')#this loop places all the tiles on the map randomlywhile X_Loop <= 10:    #do one vertical column    while Y_Loop <= 10:   #generate a random number   tile_desig = random.randint(1,3)   #add the random number to the list of tile numbers   #the tile number corresponds to the terrain type and the image file   Terrain_num_List.append(tile_desig)   Terrain_X_List.append(X_Loop)   Terrain_Y_List.append(Y_Loop)   #pick the image file based upon the random number generated   if tile_desig == 1:  Tile_Choose = Img1   elif tile_desig == 2:  Tile_Choose = Img2   elif tile_desig == 3:  Tile_Choose = Img3   #tell the tile where to go, due to the nature of a hexmap, the tiles   #cannot simply go straight up and down or straignt left and right   #so the tiles must be offset to make their edges line up   X_Pos = (X_Loop * 84) + 80   if (X_Loop + 1) % 2 == 0:  Y_Pos = (Y_Loop * 90) + 90   elif (X_Loop + 1) % 2 != 0:  Y_Pos = ((Y_Loop + 1) * 90) - 45   #create an instance of a hex tile sprite and add it to the terrain list   Terrain_List.append(Hex_Tile(X_Loop, Y_Loop, Tile_Choose))   #add the X and Y values of the current tile to the lists of coordinates   TerrainX.append(X_Pos)   TerrainY.append(Y_Pos)   Y_Loop = Y_Loop + 1   #also due to the nature of a hex map, the vertical columns cannot all   #be the same length, every other one is one tile shorter than its neighbors   #as such this ensures that this happens   if (X_Loop + 1) % 2 == 0 and Y_Loop == 10:  Y_Loop = 11    #once we reach the end of this particular vertical column, go back    #and start a new one    if Y_Loop >= 10:   Y_Loop = 0    #if Columntest == 0:   #Columntest = 1    #elif Columntest == 1:   #Columntest = 0    #move over to the left once    X_Loop = X_Loop + 1I cannot figure out why the game is slowing down so much when I institute this change, and according to others on the thread I mentioned, that caching method seems to work for them.  Can anyone tell me why it won't work for me?Thanks in advance.[Edited by - Whirled Peas on May 18, 2010 11:28:44 PM]
  Your code would be much easier to read if you enclosed it in [ source ] tags, preferably with a lang="python" to get proper syntax highlighting. This is especially a killer for Python, since we need to see the indent levels to figure out what scope various bits of code are referring to! Without having dedicated much effort to deciphering your code, my guess is that you're instantiating a bunch of Surfaces every frame; that could easily create the kind of slowdown you describe. In general, when you have performance problems, you should profile your program to see where they are. For Python, that means using cProfile. It's very handy; you should become familiar with its use. I have a caching image manager class written in Python that doesn't have any slowdown problems. You can take a look at it here (the entire project is available as open-source here, so you can see how it's used). Mine is a bit more complicated than yours, largely because in addition to loading images, it also handles some drawing logic (which is really handy now that I'm looking into transitioning to OpenGL for drawing), and it handles loading entire sequences of images instead of just single ones.   ;  ok, well aparently for some reason when I was calling pygame.image.load directly within the sprite class to load the image file, it was causing the slowdown.  In stead I am using a function which sets up the file path and loads the file for me, strangely though it uses the same statement to actually load the image.  I'm not sure why it would make a major slowdown when directly using pygame.image.load as opposed to calling it indirectly through a function, anybody have any ideas?this is the function[source lang="python" #function for loading an image filedef load_image1(name,colorkey = None):    #determine the path for the image files to be loaded    fullname = os.path.join('data', name)    #try to load the specified image file    try:   image = pygame.image.load(fullname)    #if the file is not found, show an error and exit the system    except pygame.error, message:   print 'Cannot load: ', fullname   raise SystemExit, message    #convert the image file for the screen, allow for alpha information    image = image.convert_alpha()    #return an image file    return image