diff options
Diffstat (limited to 'textures.py')
-rw-r--r-- | textures.py | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/textures.py b/textures.py new file mode 100644 index 0000000..ad0169d --- /dev/null +++ b/textures.py @@ -0,0 +1,406 @@ +from tkinter import PhotoImage + + +# tell pylint to ignore long lines in this file, since they make more sense +# to not be linewrapped +# +# ignore a particular guideline "when applying the guideline would make the code less readable" +# https://peps.python.org/pep-0008 +# +# pylint: disable=line-too-long +class Textures: + """Static class containing game textures""" + STAR = [ + ["#AAAAAA"] + ] + + ENEMY = [ + [ + [None, "#00E436", "#008751", "#008751", None, None, None, ], + ["#00E436", "#00E436", "#00E436", None, None, "#008751", None, ], + ["#008751", "#00E436", "#00E436", None, None, "#00E436", "#008751",], + [None, "#008751", "#008751", None, "#00E436", "#00E436", "#008751",], + [None, None, None, "#00E436", "#00E436", "#00E436", "#00E436",], + [None, None, "#00E436", "#00E436", "#1D2B53", "#00E436", "#008751",], + [None, None, "#008751", "#00E436", "#1D2B53", "#1D2B53", "#00E436",], + [None, None, "#008751", "#008751", "#00E436", "#FF004D", "#00E436",], + [None, "#1D2B53", None, "#008751", "#008751", "#00E436", "#00E436",], + [None, "#008751", "#00E436", None, "#008751", "#1D2B53", "#1D2B53",], + ["#008751", "#00E436", "#00E436", "#00E436", None, "#1D2B53", "#008751",], + ["#00E436", "#00E436", "#00E436", None, None, None, None, ], + ["#008751", "#00E436", "#00E436", "#00E436", "#008751", None, None, ], + ["#1D2B53", "#008751", "#00E436", "#008751", None, None, None, ], + ], + [ + [None, None, "#C2C3C7", "#1D2B53", None, None, None, ], + [None, None, "#83769C", "#C2C3C7", "#1D2B53", None, None, ], + [None, None, None, "#83769C", "#C2C3C7", "#83769C", "#C2C3C7",], + ["#83769C", "#1D2B53", None, None, "#83769C", "#C2C3C7", "#C2C3C7",], + ["#83769C", "#83769C", "#83769C", "#1D2B53", "#C2C3C7", "#83769C", "#C2C3C7",], + ["#1D2B53", "#C2C3C7", "#83769C", "#83769C", "#83769C", "#7E2553", "#1D2B53",], + ["#C2C3C7", "#C2C3C7", "#1D2B53", None, "#C2C3C7", "#7E2553", "#7E2553",], + ["#C2C3C7", "#C2C3C7", None, None, "#83769C", "#C2C3C7", "#C2C3C7",], + ["#C2C3C7", "#C2C3C7", "#C2C3C7", "#83769C", "#1D2B53", None, None, ], + ["#83769C", "#C2C3C7", "#C2C3C7", "#83769C", None, None, None, ], + ["#1D2B53", "#C2C3C7", "#83769C", "#1D2B53", None, None, None, ], + [None, "#C2C3C7", "#83769C", "#83769C", None, None, None, ], + [None, "#1D2B53", "#83769C", "#1D2B53", None, None, None, ], + ], + [ + [None, None, None, None, "#7E2553", "#FFA300", "#FFA300",], + [None, None, "#7E2553", "#FFA300", "#FFA300", "#FFA300", "#FFEC27",], + [None, "#7E2553", "#FFA300", "#FFA300", "#FFEC27", "#FFEC27", "#FFEC27",], + [None, "#FFA300", "#FFA300", "#FFEC27", "#FFA300", "#FFEC27", "#FFEC27",], + ["#7E2553", "#FFA300", "#FFEC27", "#FFEC27", "#FFEC27", "#FFA300", "#FFA300",], + ["#FFA300", "#FFA300", "#FFEC27", "#FFEC27", "#FFEC27", "#FFEC27", "#FFEC27",], + ["#AB5236", "#AB5236", "#000000", "#000000", "#FFA300", "#FFEC27", "#FFEC27",], + ["#AB5236", "#AB5236", "#1D2B53", "#FF004D", "#000000", "#FFA300", "#FFEC27",], + ["#AB5236", "#FFA300", "#AB5236", "#1D2B53", "#1D2B53", "#AB5236", "#AB5236",], + ["#7E2553", "#AB5236", "#FFA300", "#AB5236", "#AB5236", "#FFA300", "#FFA300",], + ["#7E2553", "#7E2553", "#AB5236", "#AB5236", "#AB5236", "#AB5236", "#AB5236",], + [None, "#7E2553", "#7E2553", "#7E2553", None, None, None, ], + ] + ] + + ROCK1 = [ + [None, None, "#FFA300", "#FFA300", "#FFA300", "#FFA300", "#5F574F", "#1D2B53", None, None, None, None, ], + [None, "#FFA300", "#FFA300", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", None, None, None, ], + ["#FFA300", "#FFA300", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", None, None, ], + ["#FFA300", "#5F574F", "#1D2B53", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", "#1D2B53", "#5F574F", "#5F574F", "#1D2B53", None, ], + ["#5F574F", "#5F574F", "#5F574F", "#FFA300", "#5F574F", "#1D2B53", "#5F574F", "#5F574F", "#FFA300", "#5F574F", "#5F574F", None, ], + ["#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", "#5F574F", "#5F574F", "#FFA300", "#5F574F", "#5F574F", "#1D2B53",], + [None, "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#FFA300", "#FFA300", "#5F574F", "#5F574F", "#5F574F", "#1D2B53",], + [None, "#1D2B53", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", "#1D2B53",], + [None, "#1D2B53", "#1D2B53", "#1D2B53", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53",], + [None, None, "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53",], + [None, None, None, "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", None, ], + [None, None, None, None, None, None, "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", None, None, ], + ] + + ROCK2 = [ + [None, None, None, None, "#FFA300", "#FFA300", "#5F574F", "#FFA300", "#5F574F", None, None, None, ], + [None, None, None, "#FFA300", "#FFA300", "#5F574F", "#5F574F", "#1D2B53", "#5F574F", "#1D2B53", "#1D2B53", None, ], + [None, None, "#FFA300", "#FFA300", "#5F574F", "#5F574F", "#1D2B53", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", "#1D2B53",], + [None, "#FFA300", "#FFA300", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#FFA300", "#5F574F", "#5F574F", "#1D2B53",], + [None, "#FFA300", "#5F574F", "#1D2B53", "#1D2B53", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#1D2B53",], + [None, "#5F574F", "#1D2B53", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", "#1D2B53",], + [None, None, "#1D2B53", "#5F574F", "#5F574F", "#FFA300", "#5F574F", "#5F574F", "#1D2B53", "#1D2B53", "#1D2B53", None, ], + [None, None, None, "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", None, None, None, ], + ] + + ROCK3 = [ + [None, None, None, None, None, None, None, None, None, "#FFA300", "#FFA300", "#5F574F", "#5F574F", "#5F574F", None, None, ], + [None, None, None, None, "#FFA300", "#FFA300", "#FFA300", "#FFA300", "#FFA300", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", None, ], + [None, "#FFA300", "#FFA300", "#FFA300", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", "#5F574F", "#1D2B53", "#1D2B53",], + ["#FFA300", "#FFA300", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", "#5F574F", "#FFA300", "#1D2B53", "#1D2B53",], + ["#FFA300", "#5F574F", "#5F574F", "#1D2B53", "#1D2B53", "#5F574F", "#5F574F", "#1D2B53", "#1D2B53", "#1D2B53", "#5F574F", "#5F574F", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53",], + ["#5F574F", "#5F574F", "#1D2B53", "#5F574F", "#5F574F", "#FFA300", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", None, ], + ["#1D2B53", "#5F574F", "#5F574F", "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", None, None, None, None, None, None, None, None, None, ], + [None, "#1D2B53", "#1D2B53", "#1D2B53", "#1D2B53", None, None, None, None, None, None, None, None, None, None, None, ], + ] + + ROCK4 = [ + [None, None, "#5F574F", "#FFA300", "#FFA300", "#5F574F", None, ], + [None, "#5F574F", "#FFA300", "#1D2B53", "#5F574F", "#5F574F", "#1D2B53",], + [None, "#FFA300", "#1D2B53", "#5F574F", "#5F574F", "#1D2B53", "#1D2B53",], + ["#FFA300", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", "#1D2B53",], + ["#FFA300", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", "#1D2B53", None, ], + ["#5F574F", "#5F574F", "#1D2B53", "#1D2B53", "#1D2B53", None, None, ], + [None, "#1D2B53", "#1D2B53", "#1D2B53", None, None, None, ], + ] + + ROCK5 = [ + [None, "#FFA300", "#5F574F", "#5F574F", "#1D2B53", None, ], + ["#FFA300", "#1D2B53", "#5F574F", "#5F574F", "#5F574F", "#1D2B53",], + ["#5F574F", "#5F574F", "#5F574F", "#5F574F", "#5F574F", "#1D2B53",], + ["#1D2B53", "#5F574F", "#5F574F", "#5F574F", "#1D2B53", None, ], + [None, "#1D2B53", "#1D2B53", "#1D2B53", None, None, ], + ] + + SHIP = [ + [None, None, None, None, None, None, None, None, ], + [None, None, None, "#83769C", "#83769C", None, None, None, ], + [None, "#83769C", "#1D2B53", "#FFF1E8", "#29ADFF", "#1D2B53", "#5F574F", None, ], + ["#83769C", "#83769C", "#7E2553", "#FFF1E8", "#29ADFF", "#1D2B53", "#5F574F", "#5F574F",], + ["#83769C", "#C2C3C7", "#83769C", "#29ADFF", "#29ADFF", "#1D2B53", "#83769C", "#5F574F",], + ["#83769C", "#C2C3C7", "#83769C", "#5F574F", "#1D2B53", "#1D2B53", "#83769C", "#5F574F",], + ["#1D2B53", "#83769C", "#5F574F", "#83769C", "#83769C", "#5F574F", "#5F574F", "#1D2B53",], + [None, "#1D2B53", "#1D2B53", None, None, "#1D2B53", "#1D2B53", None, ], + ] + + UFO = [ + [None, None, None, None, None, "#1D2B53", "#29ADFF", "#FFF1E8",], + [None, None, None, None, "#1D2B53", "#29ADFF", "#FFF1E8", "#FFF1E8",], + [None, None, None, "#1D2B53", "#29ADFF", "#29ADFF", "#29ADFF", "#29ADFF",], + [None, "#83769C", "#83769C", "#C2C3C7", "#FFF1E8", "#FFF1E8", "#C2C3C7", "#C2C3C7",], + ["#83769C", "#83769C", "#C2C3C7", "#FFF1E8", "#FFF1E8", "#C2C3C7", "#C2C3C7", "#C2C3C7",], + [None, "#7E2553", "#FF004D", "#7E2553", None, None, "#7E2553", "#FF004D",], + ] + + LAZER = [ + ["#8F8F8F"], + ["#F8F8F8"], + ["#F8F8F8"], + ["#F8F8F8"], + ["#F8F8F8"], + ["#8F8F8F"] + ] + + SMALLENEMY =[ + [ + [None, "#00E436", "#008751", None, ], + ["#00E436", "#008751", None, None, ], + ["#008751", "#008751", "#00E436", "#00E436",], + [None, "#00E436", "#1D2B53", "#00E436",], + [None, "#00E436", "#FF004D", "#00E436",], + ["#008751", "#00E436", "#008751", "#008751",], + ["#00E436", "#1D2B53", None, None, ], + ["#008751", "#00E436", "#00E436", None, ], + ], + [ + [None, "#7E2553", "#FFA300",], + ["#7E2553", "#FFA300", "#FFEC27",], + ["#AB5236", "#FFA300", "#FFA300",], + ["#AB5236", "#1D2B53", "#AB5236",], + ["#7E2553", "#AB5236", "#FFA300",], + [None, None, None, ], + ["#FFA300", "#AB5236", None, ], + ["#AB5236", "#7E2553", None, ], + ], + [ + ["#FF004D", None, "#7E2553", "#FF004D",], + ["#7E2553", "#7E2553", "#FF004D", "#FF77A8",], + [None, "#FF004D", "#FF004D", "#FF004D",], + [None, "#7E2553", None, "#7E2553",], + ["#7E2553", "#FF004D", "#1D2B53", "#7E2553",], + ["#FF004D", "#FF004D", None, "#FF004D",], + ["#FF004D", "#7E2553", None, None, ], + ["#7E2553", "#FF004D", "#7E2553", None, ], + ], + [ + [None, "#1D2B53", "#008751",], + [None, "#008751", "#00E436",], + ["#1D2B53", "#008751", "#00E436",], + ["#1D2B53", "#7E2553", "#008751",], + [None, "#1D2B53", "#008751",], + ["#008751", "#1D2B53", None, ], + ["#008751", None, None, ], + ["#1D2B53", "#008751", None, ], + ], + [ + [None, None, "#FFA300", "#FFEC27",], + [None, "#FFA300", "#FFEC27", "#FFEC27",], + ["#AB5236", "#FFA300", "#1D2B53", "#FFA300",], + ["#FFA300", "#FFEC27", "#FFA300", "#FFEC27",], + ["#FFEC27", "#FFA300", None, "#FFEC27",], + ["#FFA300", None, None, None, ], + ["#AB5236", "#FFA300", None, "#AB5236",], + [None, "#AB5236", None, None, ], + ], + [ + [None, None, "#7E2553", "#FF77A8",], + [None, "#7E2553", "#FF77A8", "#FFCCAA",], + [None, "#FF77A8", "#FFCCAA", "#FFCCAA",], + [None, "#FFCCAA", "#1D2B53", "#FF77A8",], + [None, "#7E2553", "#FF77A8", "#FFCCAA",], + [None, "#FF77A8", "#1D2B53", "#FFCCAA",], + [None, "#FF77A8", "#1D2B53", "#FF77A8",], + [None, "#7E2553", "#FF77A8", "#7E2553",], + ], + [ + ["#1D2B53", "#83769C", "#1D2B53", None, ], + [None, "#1D2B53", "#C2C3C7", None, ], + ["#83769C", "#1D2B53", "#83769C", "#C2C3C7",], + ["#C2C3C7", "#83769C", "#C2C3C7", "#C2C3C7",], + ["#C2C3C7", "#1D2B53", "#7E2553", "#83769C",], + ["#C2C3C7", "#1D2B53", "#C2C3C7", "#C2C3C7",], + ["#1D2B53", "#83769C", "#1D2B53", None, ], + [None, "#1D2B53", "#83769C", None, ], + ], + [ + ["#1D2B53", None, None, ], + ["#29ADFF", None, None, ], + ["#29ADFF", "#1D2B53", None, ], + ["#1D2B53", "#29ADFF", "#1D2B53",], + ["#29ADFF", None, "#29ADFF",], + ["#29ADFF", "#29ADFF", None, ], + ["#29ADFF", "#29ADFF", "#1D2B53",], + ["#29ADFF", "#1D2B53", None, ], + ] + ] + + EXPLOSION =[ + [ + ["#FFEC27", "#FFEC27"], + ["#FFF1E8", "#FFEC27"], + ["#7E2553", "#7E2553"] + ], + [ + ["#7E2553", "#FFEC27"], + ["#FFEC27", "#FFF1E8"], + ], + [ + [ None, "#7E2553", "#FFEC27", "#FFEC27"], + [ "#7E2553", "#FFEC27", "#FFEC27", "#FFF1E8"], + [ "#FFEC27", "#FFEC27", "#FFF1E8", "#FFF1E8"], + [ "#FFEC27", "#FFF1E8", "#FFF1E8", "#FFF1E8"], + ] + ] + + @staticmethod + def hmirror_texture(texture): + """Horizontally mirror a texture + + :param texture: texture to mirror + """ + return [(row + row[::-1]) for row in texture] + + @staticmethod + def vmirror_texture(texture): + """Vertically mirror a texture + + :param texture: texture to mirror + """ + return texture + texture[::-1] + + @staticmethod + def recolor(texture, color): + """recolor a texture + + :param texture: texture to recolor + :param color: Color to multiply the texture with + """ + return [[None if col is None else Textures.multiply_colors(col, color) for col in row] for row in texture] + + @staticmethod + def multiply_colors(hex1, hex2): + """Multiply two RGB colours + + :param hex1: first colour + :param hex2: second colour + """ + color1 = Textures.hex_to_rgb(hex1) + color2 = Textures.hex_to_rgb(hex2) + return Textures.rgb_to_hex([color1[i] * color2[i] for i in range(len(color1))]) + + @staticmethod + def hex_to_rgb(value): + """Convert a hexadecimal colour value to red green and blue + + :param value: hex value + """ + value = value.lstrip('#') + length = len(value) + return tuple(int(value[i:i + length // 3], 16)/256 for i in range(0, length, length // 3)) + + @staticmethod + def rgb_to_hex(value): + """Convert red green and blue value to a hexadecimal representation + + :param value: RGB value + """ + return "#" + "".join(f"{int(v*256):02X}" for v in value) + + @staticmethod + def white_texture(texture): + """Replace all coloured pixels with white + + :param texture: Texture to replace on + """ + return [[None if col is None else "#FFFFFF" for col in row] for row in texture] + + @staticmethod + def load_textures(texture_factory): + """Load all textures within this class + + :param texture_factory: + """ + texture_factory.load_texture( + "ufo", Textures.hmirror_texture(Textures.UFO)) + texture_factory.load_texture("star", Textures.STAR) + + texture_factory.load_texture("ship", Textures.SHIP) + texture_factory.load_texture( + "ship:white", Textures.white_texture(Textures.SHIP)) + + texture_factory.load_texture("rock1", Textures.ROCK1) + texture_factory.load_texture("rock2", Textures.ROCK2) + texture_factory.load_texture("rock3", Textures.ROCK3) + texture_factory.load_texture("rock4", Textures.ROCK4) + texture_factory.load_texture("rock5", Textures.ROCK5) + + texture_factory.load_texture( + "lazer:white", Textures.recolor(Textures.LAZER, "#ffffff")) + texture_factory.load_texture( + "lazer:red", Textures.recolor(Textures.LAZER, "#f2aaaa")) + texture_factory.load_texture( + "lazer:yellow", Textures.recolor(Textures.LAZER, "#f2ffaa")) + + for i, enemy in enumerate(Textures.SMALLENEMY): + name = f"smallenemy{i}" + texture = Textures.hmirror_texture(enemy) + texture_factory.load_texture(name, texture) + texture_factory.load_texture( + f"{name}:white", Textures.white_texture(texture)) + evil_texture = Textures.recolor(texture, "#FF5555") + texture_factory.load_texture(f"{name}_evil", evil_texture) + texture_factory.load_texture( + f"{name}_evil:white", Textures.white_texture(evil_texture)) + + for i, enemy in enumerate(Textures.ENEMY): + name = f"enemy{i}" + texture_factory.load_texture(name, Textures.hmirror_texture(enemy)) + texture_factory.load_texture( + f"{name}:white", Textures.white_texture(Textures.hmirror_texture(enemy))) + + texture_factory.load_texture("explosion3", Textures.EXPLOSION[0]) + texture_factory.load_texture("explosion2", Textures.hmirror_texture( + Textures.vmirror_texture(Textures.EXPLOSION[1]))) + texture_factory.load_texture("explosion1", Textures.hmirror_texture( + Textures.vmirror_texture(Textures.EXPLOSION[2]))) + + +class TextureFactory: + """Object that deals with loading and scaling textures""" + + def __init__(self, scale) -> None: + """Initialise the texture factory + + :param scale: the amount of pixels to upscale by + :rtype: None + """ + self.textures = {} + self.scale = scale + + def load_texture(self, namespace, texture_matrix): + """Load and upscale a texture + + :param namespace: namespace to save this texture to + :param texture_matrix: A matrix of hex colours that represents the texture + """ + if namespace not in self.textures: + height = len(texture_matrix) * self.scale + width = len(texture_matrix[0]) * self.scale + photo_image = PhotoImage(width=width, height=height) + + for matrix_y, row in enumerate(texture_matrix): + for matrix_x, color in enumerate(row): + if color is not None: + pixel_string = ( + "{" + f"{color} "*self.scale + "} ") * self.scale + photo_image.put( + pixel_string, (matrix_x*self.scale, matrix_y*self.scale)) + + self.textures[namespace] = photo_image + return photo_image + return self.get_image(namespace) + + def get_image(self, namespace): + """Get a loaded image + + :param namespace: to load the image from + """ + if namespace not in self.textures: + raise Exception( + f"Provided namespace \"{namespace}\" has not been loaded!") + return self.textures[namespace] |