Return to repo list

tzed

Simple story-driven open world 2D CRPG.
Return to HMagellan.com

commit 6b568a38808e020410623b7319e0ee0b7077b1b6
parent 95f1cf6eedc7b5eeac929d91d8e0efffc5cecc3c
Author: Erik Letson <hmagellan@hmagellan.com>
Date:   Wed, 22 Sep 2021 23:03:11 -0500

universal sprite with colorchange

Diffstat:
Mdata/dungeons/testdun1/dungeon.json | 1+
Msrc/dungeon.py | 66++++++++++++++++++++----------------------------------------------
Msrc/entity.py | 80++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Msrc/game.py | 4++--
4 files changed, 80 insertions(+), 71 deletions(-)

diff --git a/data/dungeons/testdun1/dungeon.json b/data/dungeons/testdun1/dungeon.json @@ -5,6 +5,7 @@ "sheet" : "dungeon1", "entrance" : [0, 0], "direction" : 1, + "north_color" : 7, "layout" : [ [ [ diff --git a/src/dungeon.py b/src/dungeon.py @@ -1,4 +1,5 @@ import pygame +from . import entity from .gamelib import * ############## @@ -7,7 +8,6 @@ from .gamelib import * # This file contains: # 1. The 'Dungeon' class, which represents the over-the-shoulder maze/battle dungeon locations. -# 2. The 'DungeonSprite' class, which represents the visual elements of a dungeon such as architecture. ################################# # Section 1 - The Dungeon class # @@ -19,18 +19,22 @@ class Dungeon(object): for the dungeon-crawling sections of the game. """ - def __init__(self, game, name, disp_str, width, height, sheetname, enter_dir, entrance, layout): + def __init__(self, game, name, definition): # Saved vals self.game = game self.name = name - self.display_name = disp_str - self.maze_width = width - self.maze_height = height - self.sheetname = sheetname - self.entrance_direction = enter_dir - self.entrance_cell = entrance - self.layout_definition = layout + self.definition = definition + + # Definition-derived vals + self.display_name = definition["display_name"] + self.maze_width = definition["width"] + self.maze_height = definition["height"] + self.sheetname = definition["sheet"] + self.entrance_direction = definition["direction"] + self.entrance_cell = definition["entrance"] + self.north_color = definition["north_color"] + self.layout_definition = definition["layout"] # Other vals self.direction = 0 @@ -95,48 +99,18 @@ class Dungeon(object): workcell = self.layout_definition[self.current_floor][self.current_cell[1]][self.current_cell[0]][DIRECTIONS[self.direction]] # Add the individual components - self.dungeon_view.add(DungeonSprite(self.game.sheets[self.sheetname + "_fc"].sprites[tuple(workcell["ceiling"])], self.game.viewport_rect.topleft)) - self.dungeon_view.add(DungeonSprite(self.game.sheets[self.sheetname + "_fc"].sprites[tuple(workcell["floor"])], (self.game.viewport_rect.topleft[0], self.game.viewport_rect.topleft[1] + 347))) - self.dungeon_view.add(DungeonSprite(self.game.sheets[self.sheetname + "_w"].sprites[tuple(workcell["l_wall"])], self.game.viewport_rect.topleft)) - self.dungeon_view.add(DungeonSprite(self.game.sheets[self.sheetname + "_w"].sprites[tuple(workcell["r_wall"])], (self.game.viewport_rect.topleft[0] + 462, self.game.viewport_rect.topleft[1]))) - self.dungeon_view.add(DungeonSprite(self.game.sheets[self.sheetname + "_h"].sprites[tuple(workcell["horizon"])], (self.game.viewport_rect.center[0] - 121, self.game.viewport_rect.center[1] - 91))) + self.dungeon_view.add(entity.CustomSprite(self.game.sheets[self.sheetname + "_fc"].sprites[tuple(workcell["ceiling"])], self.game.viewport_rect.topleft)) + self.dungeon_view.add(entity.CustomSprite(self.game.sheets[self.sheetname + "_fc"].sprites[tuple(workcell["floor"])], (self.game.viewport_rect.topleft[0], self.game.viewport_rect.topleft[1] + 347))) + self.dungeon_view.add(entity.CustomSprite(self.game.sheets[self.sheetname + "_w"].sprites[tuple(workcell["l_wall"])], self.game.viewport_rect.topleft)) + self.dungeon_view.add(entity.CustomSprite(self.game.sheets[self.sheetname + "_w"].sprites[tuple(workcell["r_wall"])], (self.game.viewport_rect.topleft[0] + 462, self.game.viewport_rect.topleft[1]))) + self.dungeon_view.add(entity.CustomSprite(self.game.sheets[self.sheetname + "_h"].sprites[tuple(workcell["horizon"])], (self.game.viewport_rect.center[0] - 121, self.game.viewport_rect.center[1] - 91))) # Add overlay elements - self.dungeon_view.add(DungeonSprite(self.game.sheets["compass"].sprites[(0, 0)], (self.game.viewport_rect.center[0] - 96, self.game.viewport_rect.top + 3))) - self.dungeon_view.add(DungeonSprite(self.game.sheets[self.sheetname + "_cd"].sprites[(self.direction, 0)], (self.game.viewport_rect.center[0] - 16, self.game.viewport_rect.top + 12))) + self.dungeon_view.add(entity.CustomSprite(self.game.sheets["compass"].sprites[(0, 0)], (self.game.viewport_rect.center[0] - 96, self.game.viewport_rect.top + 3))) + self.dungeon_view.add(entity.CustomSprite(self.game.sheets[self.sheetname + "_cd"].sprites[(self.direction, 0)], (self.game.viewport_rect.center[0] - 16, self.game.viewport_rect.top + 12), self.north_color if self.direction == 0 else None)) def update_dungeon(self, surface = None): """ Update the dungeon logic and visuals. """ self.dungeon_view.update(surface) - -####################################### -# Section 2 - The DungeonSprite class # -####################################### - -# TODO: This class, along with some of the stuff in the board.py file and the ui.py file, should probably be split off into a single, generic sprite -# class that lacks tilepos support but has things like color changing. Entity could be a child of this object. - -class DungeonSprite(pygame.sprite.Sprite): - """ - Simple sprite extension for drawing dungeon - components. - """ - - def __init__(self, image, pos): - - # Parent initialization - pygame.sprite.Sprite.__init__(self) - - # Saved values - self.image = image - self.rect = self.image.get_rect() - self.rect.topleft = pos - - def update(self, surface = None): - """ - Update this DungeonSprite. - """ - if surface != None: - surface.blit(self.image, self.rect) diff --git a/src/entity.py b/src/entity.py @@ -6,49 +6,83 @@ from .gamelib import * ############# # This file contains: -# 1. The 'Entity' object that is the extension of pygame.Sprite used throughout the game on the board. -# 2. The 'StaticEntity' and 'DynamicEntity' classes, which inherit directly from Entity and are characterized by how the board handles them. -# 3. Various other entity classes that inherit directly from Entity. -# 4. Various StaticEntity subclasses. -# 5. Various DynamicEntity subclasses. +# 1. The 'CustomSprite' object, which is a simple extension of the pygame Sprite object. +# 2. The 'Entity' object that is the extension of pygame.Sprite used throughout the game on the board. +# 3. The 'StaticEntity' and 'DynamicEntity' classes, which inherit directly from Entity and are characterized by how the board handles them. +# 4. Various other entity classes that inherit directly from Entity. +# 5. Various StaticEntity subclasses. +# 6. Various DynamicEntity subclasses. + +###################################### +# Section 1 - The CustonSprite class # +###################################### + +class CustomSprite(pygame.sprite.Sprite): + """ + CustomSprite is the simplest extension that all + sprite objects in the game source from, either + directly or through a parent relationship (e.g. + in Entities). It has only the most basic of + functionality that all sprites in the game will + need. If some visible object for some reason + needs less, it should source from the pygame + Sprite object instead. + """ + + def __init__(self, image, pos, pixcolor = None): + + # Parent initialization + pygame.sprite.Sprite.__init__(self) + + # Saved values + self.image = image + self.rect = self.image.get_rect() + self.rect.topleft = pos + self.pixcolor = pixcolor + + # Handle color replace + if self.pixcolor != None: + self.image = self.image.copy() + pygame.PixelArray(self.image).replace(BASE_COLOR, COLOR_PALETTE[self.pixcolor]) + + def update(self, surface = None): + """ + Update this DungeonSprite. + """ + if surface != None: + surface.blit(self.image, self.rect) ################################ -# Section 1 - The Entity class # +# Section 2 - The Entity class # ################################ -class Entity(pygame.sprite.Sprite): +class Entity(CustomSprite): """ The Entity object is a parent class for visible - game objects, excluding tiles and UI elements. - Entities are things like NPCs. + game objects, excluding things like UI elements. + Entities are things like NPCs which are always + characterised by taking a cellpos and tilepos. """ def __init__(self, image, cellpos, tilepos, pixcolor = None): # Parent initialization - pygame.sprite.Sprite.__init__(self) + super().__init__(image, (0, 0), pixcolor) # Saved values - self.image = image - self.rect = self.image.get_rect() self.cellpos = cellpos self.tilepos = tilepos - self.pixcolor = pixcolor - # Color - if self.pixcolor != None: - self.image = self.image.copy() - pygame.PixelArray(self.image).replace(BASE_COLOR, COLOR_PALETTE[self.pixcolor]) - def update(self, surface = None, viewport = None): """ - Update this entity on the screen. + Overwrite of the CustomSprite update() + method. Update this entity on the screen. """ if surface != None and viewport != None and self.rect.colliderect(viewport): surface.blit(self.image, self.rect) ############################################## -# Section 2 - StaticEntity and DynamicEntity # +# Section 3 - StaticEntity and DynamicEntity # ############################################## class StaticEntity(Entity): @@ -85,7 +119,7 @@ class DynamicEntity(Entity): super().__init__(image, cellpos, tilepos, pixcolor) ######################################### -# Section 3 - Various Entity Subclasses # +# Section 4 - Various Entity Subclasses # ######################################### class Tile(Entity): @@ -125,7 +159,7 @@ class PlayerEntity(Entity): super().__init__(image, cellpos, tilepos, pixcolor) ############################################### -# Section 4 - Various StaticEntity Subclasses # +# Section 5 - Various StaticEntity Subclasses # ############################################### class OverlayEntity(StaticEntity): @@ -143,7 +177,7 @@ class OverlayEntity(StaticEntity): self.event = event ################################################ -# Section 5 - Various DynamicEntity Subclasses # +# Section 6 - Various DynamicEntity Subclasses # ################################################ class NPCEntity(StaticEntity): diff --git a/src/game.py b/src/game.py @@ -137,7 +137,7 @@ class Game(object): for d in dungeonlist["dungeons"]: with open(os.path.join(DUNGEON_PATH, d, "dungeon.json")) as dj: dungeondef = json.load(dj) - nd = dungeon.Dungeon(self, d, dungeondef["display_name"], dungeondef["width"], dungeondef["height"], dungeondef["sheet"], dungeondef["direction"], tuple(dungeondef["entrance"]), dungeondef["layout"]) + nd = dungeon.Dungeon(self, d, dungeondef) self.loaded_dungeons[d] = nd def build_ui(self): @@ -226,7 +226,7 @@ class Game(object): display in battles and dungeons. """ for p in self.party: - pg = dungeon.DungeonSprite(self.sheets[self.party[p]["party_sheet"]].sprites[tuple(self.party[p]["party_sprite"])], (self.viewport_rect.left + (256 * self.party[p]["position"]), self.viewport_rect.center[1] + (48 * self.party[p]["row"]))) + pg = entity.CustomSprite(self.sheets[self.party[p]["party_sheet"]].sprites[tuple(self.party[p]["party_sprite"])], (self.viewport_rect.left + (256 * self.party[p]["position"]), self.viewport_rect.center[1] + (48 * self.party[p]["row"])), self.party[p]["color"]) self.party_group.add(pg) def move_player_on_board(self, offset):