Last active
August 26, 2020 13:41
-
-
Save Mega-JC/ed7d7039e8cd74da365031032db63ff7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pygame | |
from pygame import Surface, Rect | |
pygame.init() | |
listtypes = set((list, tuple)) | |
pygame_classes = set((Surface, Rect)) | |
_text0 = "invalid Spritesheet coordinate: " | |
_text1 = ". Coordinates must be like this: (x, y, width, height)" | |
default_group_name = "group.000" | |
default_image_name = "sprite.000" | |
default_ss_name = "spritesheet.000" | |
def new_name(name, lead_zeros=3, from_zero=False): # Generates new names by incrementing them | |
if not name.isspace(): | |
if name != "": | |
is_num = name.isnumeric() | |
if is_num: | |
name = "("+name+")" | |
num_found = True | |
end_num = "" | |
index = len(name)-1 | |
while num_found and index >= 0: | |
if name[index].isnumeric() == False: | |
num_found = False | |
break | |
if int(name[index]) in range(10): | |
end_num = name[index] + end_num | |
index -= 1 | |
else: | |
num_found = False | |
if end_num == "": | |
new_n = name+"."+"0"*(lead_zeros-1)+("0" if from_zero else "1") | |
if ("(" or ")") in new_n: | |
new_n = new_n.replace("(", "") | |
new_n = new_n.replace(")", "") | |
return new_n | |
else: | |
end_num = str(int(end_num)+1) | |
add_dot = "" if name[index] == "." else "." | |
new_end_num = add_dot+"0"*max(lead_zeros-len(end_num), 0) + str(int(end_num)) | |
new_n = name[:index+1]+new_end_num | |
if ("(" or ")") in new_n: | |
new_n = new_n.replace("(", "") | |
new_n = new_n.replace(")", "") | |
return new_n | |
else: | |
return name | |
else: | |
return name | |
class Spritesheet(): | |
__slots__ = "_name", "_path", "_colorkey", "_group_name", "_isalpha", "_sprite_coords", "_sprite_images", "_sheet", "_corner_colorkey", "_sheetsize" | |
def __init__(self, path, name=None, alpha=True, colorkey=None, _=True, _c__=1): # _c__ and _ should be ignored, they are used for copying | |
self._name = "spritesheet" if not name else name | |
if _c__: | |
self._path = path | |
self._colorkey = colorkey | |
self._group_name = default_group_name | |
self._isalpha = alpha | |
self._sprite_coords = {} | |
self._sprite_images = {} | |
if _: | |
self._config_sheet_1(path, alpha=alpha, colorkey=colorkey) | |
else: | |
self._sheet = None | |
self._corner_colorkey = None | |
self._colorkey = None | |
self._sheet = None | |
self._sheetsize = None | |
def _config_sheet_1(self, path, alpha=True, colorkey=None): | |
""" Do not use this method directly, it is neeeded to configure a spritesheet object""" | |
self._sheet = sheet = pygame.image.load(path) | |
self._corner_colorkey = self._sheet.get_at((0, 0)) | |
if colorkey is not None: | |
if colorkey == -1: | |
sheet.set_colorkey(self._corner_colorkey) | |
self._colorkey = self._corner_colorkey | |
else: | |
sheet.set_colorkey(colorkey) | |
self._colorkey = colorkey | |
self._sheet.convert() | |
elif alpha: | |
self._sheet = sheet.convert_alpha() | |
self._sheetsize = sheet.get_size() | |
def _config_sheet_2(self, alt_sheet): | |
self._sheet = alt_sheet | |
def __rcv(self, spritesheet): | |
"""Do not use this method directly, it is needed for copying Spritesheets.""" | |
sattr = self.__setattr__ | |
s_gattr = spritesheet.__getattribute__ | |
for key in self.__slots__: | |
v = s_gattr(key) | |
if v.__class__ in pygame_classes: | |
sattr(key, v.copy()) | |
elif key == "_sprite_coords": | |
vd = {} | |
if v: | |
for key2 in v.keys(): | |
vd[key2] = [v[key2][i][:] for i in range(len(v[key2]))] | |
sattr(key, vd) | |
elif key == "_sprite_images": | |
vd = {} | |
if v: | |
for key2 in v.keys(): | |
vd[key2] = [v[key2][i].copy() for i in range(len(v[key2]))] | |
sattr(key, vd) | |
elif key != "_name": | |
sattr(key, v) | |
return self | |
def copy(self): | |
return Spritesheet(self._path, _c__=0).__rcv(self) | |
def rename(self, name): | |
if isinstance(name, str): | |
self._name = name | |
def get_name(self): | |
return self._name | |
@property | |
def name(self): | |
return self._name | |
def get_ss_colorkey(self): | |
self._colorkey = self._sheet.get_colorkey() | |
return self._colorkey | |
def set_ss_colorkey(self, colorkey): | |
if colorkey != None: | |
if colorkey == -1: | |
self._sheet.set_colorkey(self._corner_colorkey) | |
else: | |
self._sheet.set_colorkey(colorkey) | |
self._colorkey = self._sheet.get_colorkey() | |
def is_alpha(self): | |
return self._isalpha | |
def add_sprite_group_coords(self, group_name, coords=(), reverse=False): | |
"""add new coordinates to a sprite group. a new group is made if the given group name does not yet exist""" | |
if group_name in self._sprite_coords.keys(): | |
coords = list(coords) | |
if reverse: | |
coords.reverse() | |
for i in range(len(coords)): | |
if type(coords[i]) == pygame.Rect: | |
coords[i] = (coords[i].left, coords[i].top, coords[i].width, coords[i].height) | |
elif type(coords[i]) not in listtypes or len(coords[i]) != 4: | |
p = pygame.error(_text0+str(coords[i])+_text1) | |
raise p | |
new_subsurface = self._sheet.subsurface | |
self._sprite_coords[group_name] += coords | |
self._sprite_images[group_name].extend([new_subsurface(coord) for coord in coords]) | |
else: | |
self.add_sprite_group(group_name, coords, reverse=reverse) | |
def group_image_count(self, group_name): | |
if group_name in self._sprite_coords.keys(): | |
return len(self._sprite_coords[group_name]) | |
def add_sprite_group(self, group_name=None, coords=(), reverse=False): | |
if group_name is None: | |
group_name = self._group_name | |
ks = self._sprite_coords.keys() | |
if group_name in ks: | |
group_name = new_name(max(ks)) # this increments the default group_name by one | |
self._sprite_coords[group_name] = [] | |
self._sprite_images[group_name] = [] | |
self.add_sprite_group_coords(group_name, coords=coords, reverse=reverse) | |
return group_name | |
def reverse_sprite_group(self, group_name): | |
"""reverses the order of images.""" | |
if group_name in self._sprite_coords.keys(): | |
self._sprite_coords[group_name].reverse() | |
self._sprite_coords[group_name].reverse() | |
def delete_sprite_group(self, group_name): | |
"""Deletes a sprite group and all information related to it.""" | |
if group_name in self._sprite_images.keys(): | |
del self._sprite_coords[group_name] | |
del self._sprite_images[group_name] | |
#def _get_sprite(self, coord): | |
# img = pygame.Surface.subsurface(coord) | |
# | |
# #img.blit(self._sheet, (0,0), area=coord) | |
# if not self._isalpha: | |
# img.set_colorkey(self._colorkey) | |
# return img | |
def get_group_image(self, group_name, index, wrap_around=True): | |
"""Get a surface from a group.""" | |
spr_coords = self._sprite_coords | |
spr_images = self._sprite_images | |
if group_name in spr_coords: | |
if wrap_around: | |
index %= len(spr_coords[group_name]) | |
try: | |
return spr_images[group_name][int(index)] | |
except IndexError as i: | |
i.args = ("The given index is out of range for the selected group.",) | |
else: | |
err = KeyError("The name '"+str(group_name)+"' does not exist in this Spritesheet object.") | |
raise err | |
def get_group_coords(self, group_name=None): | |
"""Returns the dictionary maintaining the group subsurface areas of the spritesheet.""" | |
if group_name is None: | |
return self._sprite_coords | |
else: | |
return self._sprite_coords[group_name][:] | |
def get_group_images(self, group_name=None): | |
"""Returns the dictionary maintaining the group subsurfaces of the spritesheet.""" | |
if group_name is None: | |
return self._sprite_images | |
else: | |
return (img.copy() for img in self._sprite_images[group_name]) | |
def get_sheet(self, copy=True): | |
"""get the underlying spritesheet surface as a copy()""" | |
if copy: | |
return self._sheet.copy() | |
return self._sheet | |
def __str__(self): | |
return '<(Spritesheet named "{0}", SHEETSIZE: {1}x{2}, GROUPS: {3})>'.format(self._name, self._sheetsize[0], self._sheetsize[1], list(self._sprite_coords.keys())).replace("[", "").replace("]", "") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment