commit 6b568a38808e020410623b7319e0ee0b7077b1b6
parent 95f1cf6eedc7b5eeac929d91d8e0efffc5cecc3c
Author: Erik Letson <hmagellan@hmagellan.com>
Date: Wed, 22 Sep 2021 23:03:11 -0500
universal sprite with colorchange
Diffstat:
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):