Return to repo list

heart-of-gold

Tactical RPG written in python, using pygame.
Return to HMagellan.com

images.py (5965B)


      1 import pygame, os, json
      2 from . import manager
      3 from .constants import *
      4 
      5 #############
      6 # images.py #
      7 #############
      8 
      9 # This file contains:
     10 #   1. The 'SheetManager' class, which is a Manager object that handles sheets (e.g. loading)
     11 #   2. The 'Sheet' class, which is used to represent enumerated spritesheets
     12 
     13 ###################################
     14 # Section 2 - SheetManager Object #
     15 ###################################
     16 
     17 class SheetManager(manager.Manager):
     18     """
     19     SheetManager handles loading and managing sheets. It is
     20     talked to in order to get loaded sheets. SheetManager also
     21     knows all animations and is talked to to get info about
     22     them.
     23     """
     24 
     25     def __init__(self, game, bus, camera, name):
     26 
     27         super().__init__(game, bus, camera, name)
     28 
     29         # Important values
     30         self.sheets_def = {}
     31         self.loaded_sheets = {}
     32         self.anims_def = {}
     33         self.animations = {}
     34 
     35         # This manager should perform an initial update
     36         self.update(None)
     37 
     38     def load_sheets_from_json(self, sheet_json):
     39         """
     40         Load sheets from the given definition JSON file. Note
     41         that sheets must be loaded AFTER animations.
     42         """
     43         with open(os.path.join(JSON_PATH, sheet_json)) as df: self.sheets_def = json.load(df)
     44 
     45         for j in self.sheets_def:
     46             an = {}
     47             if self.sheets_def[j]["anim_class"] != None:
     48                 an = self.animations[self.sheets_def[j]["anim_class"]]
     49             self.loaded_sheets[j] = Sheet(self, self.sheets_def[j]["filename"], j, tuple(self.sheets_def[j]["dimensions"]), self.sheets_def[j]["total_sprites"], an, self.sheets_def[j]["alpha"])
     50 
     51     def load_animations_from_json(self, anim_json):
     52         """
     53         Load animations from the given definition JSON file.
     54         Note that animations must be loaded BEFORE sheets.
     55         """
     56         with open(os.path.join(JSON_PATH, anim_json)) as anf: self.anims_def = json.load(anf)
     57 
     58         self.animations = self.anims_def
     59         for c in self.anims_def:
     60             for a in self.anims_def[c]:
     61                 for i in range(0, len(self.anims_def[c][a])):
     62                     for v in self.anims_def[c][a][i]:
     63                         if type(self.anims_def[c][a][i][v]) == list:
     64                             self.animations[c][a][i][v] = tuple(self.anims_def[c][a][i][v])
     65 
     66     def load_image(self, filename, alpha = False):
     67         """
     68         Load an image file as a PyGame image. This is generic
     69         and can function even outside of the normal sheet
     70         dynamic that the game uses.
     71         """
     72         if alpha:
     73             im = pygame.image.load(os.path.join(IMAGE_PATH, filename)).convert_alpha()
     74         else:
     75             im = pygame.image.load(os.path.join(IMAGE_PATH, filename)).convert()
     76         return im
     77 
     78     def get_sheet(self, name):
     79         """
     80         Return the sheet matching name if it exists.
     81         """
     82         if name in self.loaded_sheets.keys():
     83             return self.loaded_sheets[name]
     84 
     85     def expose(self):
     86         """
     87         Expose sheet info to the ManagerBus.
     88         """
     89         data = {
     90             "sheets" : self.loaded_sheets,
     91             "animations" : self.animations
     92         }
     93         self.bus.record(self.name, data)
     94 
     95 ############################
     96 # Section 3 - Sheet Object #
     97 ############################
     98 
     99 class Sheet(object):
    100     """
    101     Class for the enumerated spritesheets that are used to get
    102     images for entities. Supports regularized spritesheets only
    103     (that is, all sprites are the same dimensions).
    104     """
    105 
    106     def __init__(self, manager, filename, name, sprite_size, total_sprites, animations, alpha):
    107         
    108         # Important values
    109         self.manager = manager
    110         self.filename = filename
    111         self.name = name
    112         self.sprite_dimensions = sprite_size
    113         self.total_sprites = total_sprites
    114         self.sprites = {}
    115         self.animations = animations
    116         self.alpha = alpha
    117 
    118         # Try and load all sprites on the sheet, or log if we failed
    119         if not self.load_sheet(filename, sprite_size, total_sprites):
    120             self.sprites = {}
    121             print("Failed to load sheet: " + filename)
    122 
    123     def load_sheet(self, filename, sprite_size, total_sprites):
    124         """
    125         Load a sheet and divide it into subsurfaces for use as
    126         images by sprite entities.
    127         """
    128 
    129         # First, attempt to load the image file. Failing that, create
    130         # a sheet as a NoneType object
    131         try:
    132             self.sheet = self.manager.load_image(filename, self.alpha)
    133         except:
    134             self.sheet = None
    135 
    136         # Next, if the sheet exists, divide it into sprites
    137         if self.sheet != None:
    138             self.sprites = {}
    139 
    140             # Values to track progress
    141             x = 0
    142             y = 0
    143 
    144             # While there are still more sprites to load, load them
    145             while len(self.sprites) < total_sprites:
    146                
    147                 # Get a rect that can be used to make a subsurface of the sheet
    148                 new_rect = pygame.Rect((x * sprite_size[0], y * sprite_size[1]), sprite_size)
    149 
    150                 # Load image, store in our sprites dict, and set colorkey or alpha
    151                 if not self.alpha:
    152                     self.sprites[(x, y)] = self.sheet.subsurface(new_rect).convert()
    153                     self.sprites[(x, y)].set_colorkey(COLORKEY)
    154                 else:
    155                     self.sprites[(x, y)] = self.sheet.subsurface(new_rect).convert_alpha()
    156 
    157                 # Scoot over to the right
    158                 x += 1
    159 
    160                 # If we're hanging off the right side, scoot down and start
    161                 # over again from the far left
    162                 if x * sprite_size[0] >= self.sheet.get_width():
    163                     x = 0
    164                     y += 1
    165 
    166             # After the while loop, return True for success
    167             return True
    168 
    169         # No sheet exists, return False for failure
    170         else:
    171             return False