Return to repo list

heart-of-gold

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

commit e42b38f1253b684d9be7579a527d381e4f266e2e
parent ef231f44df278aeeae11cd8dd93507086e05e47e
Author: Erik Letson <hmagellan@hmagellan.com>
Date:   Sun, 13 Sep 2020 15:25:56 -0500

Tile access method improved, new functions for as much

Diffstat:
Mdata/json/ents/testmap1.json | 2+-
Msrc/board.py | 12++++++++++++
Msrc/game.py | 2+-
Msrc/vgo.py | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
4 files changed, 97 insertions(+), 29 deletions(-)

diff --git a/data/json/ents/testmap1.json b/data/json/ents/testmap1.json @@ -1,7 +1,7 @@ { "testent1" : { + "name" : "Jisella_Unit", "sheet" : "jisella_1", - "position" : [0, 0], "visible" : true, "animation" : "stand_L", "animated" : true, diff --git a/src/board.py b/src/board.py @@ -58,6 +58,18 @@ class BoardManager(manager.Manager): return (x, y, gid) return None + def get_tile_at_tile_pos(self, pos): + """ + Return (x, y, gid) if there is a tile at tile_pos 'pos', + and return None otherwise. + """ + for layer in self.current_board.tmx_data.visible_layers: + if isinstance(layer, pytmx.TiledTileLayer): + for x, y, gid in layer: + if pos == (x, y): + return (x, y, gid) + return None + def update_board(self, surface = None): """ Update the current board. diff --git a/src/game.py b/src/game.py @@ -178,4 +178,4 @@ class GameInterface(GameSubsystem): """ # Update cursor position t = self.game.board_manager.get_tile_at_position(pygame.mouse.get_pos()) - self.game.entity_manager.position_tile_cursor((t[0] * TILE_WIDTH, t[1] * TILE_HEIGHT)) + self.game.entity_manager.position_tile_cursor(t) diff --git a/src/vgo.py b/src/vgo.py @@ -1,6 +1,6 @@ import pygame, json, os from . import manager -from .constants import ENTITY_JSON_PATH +from .constants import ENTITY_JSON_PATH, TILE_WIDTH, TILE_HEIGHT ########## # vgo.py # @@ -26,7 +26,7 @@ class VisibleGameObject(pygame.sprite.Sprite): object. """ - def __init__(self, sheet, position, visible = True, animation = None, animated = False): + def __init__(self, sheet, visible = True, animation = None, animated = False): # Parent initialization super().__init__() @@ -35,7 +35,7 @@ class VisibleGameObject(pygame.sprite.Sprite): self.sheet = sheet self.image = sheet.sprites[(0, 0)] # TODO: Should this be assigned?? self.rect = self.image.get_rect() - self.rect.topleft = position # TODO: Maybe this should not be defined here? + self.rect.topleft = (0, 0) self.visible = visible # Animation values @@ -71,6 +71,13 @@ class VisibleGameObject(pygame.sprite.Sprite): self.animation_frame = 0 self.animation_timer = self.animation[self.animation_frame]["timer"] self.image = self.sheet.sprites[self.animation[self.animation_frame]["sprite"]] + + def set_position(self, pos): + """ + Assign the rect topleft to a raw position tuple, independent + of e.g. a tile. + """ + self.rect.topleft = pos def act(self): """ @@ -98,19 +105,41 @@ class VisibleGameObject(pygame.sprite.Sprite): class Entity(VisibleGameObject): """ - Entity is a class for all non-tile, non-UI-element sprite objects - that are drawn in the game. Things like character units and board - decorations/obstacles are entities. + Entities are VGOs that can occupy a tile. They are managed + by an EntityManager and record tile x, y and gid values. An + Entity does not have to occupy a tile but it can. Entities + also have a name (human-readable string set in their definition) + and a ent_id (number assigned by entity manager). """ - def __init__(self, sheet, position, visible = True, animation = None, animated = False, passable = False, tile = None): + def __init__(self, name, ent_id, sheet, visible = True, animation = None, animated = False, passable = False): # Parent initialization - super().__init__(sheet, position, visible, animation, animated) + super().__init__(sheet, visible, animation, animated) # Saved values + self.name = name + self.ent_id = ent_id self.passable = passable - self.tile = tile + + # Tile values + self.tile_pos = (-1, -1) + self.tile_gid = None + + def snap_to_tile(self): + """ + Snap the Entity to its current tile. + """ + if self.tile_pos != (-1, -1): + self.set_position((self.tile_pos[0] * TILE_WIDTH, self.tile_pos[1] * TILE_HEIGHT)) + + def assign_tile(self, tile_def): + """ + Assign a tile as this entity object's occupied tile. + Assume the values are legitimate. + """ + self.tile_pos = (tile_def[0], tile_def[1]) + self.tile_gid = tile_def[2] ######################################### # Section 3 - Various Entity subclasses # @@ -121,16 +150,11 @@ class TileCursor(Entity): Object that follows the cursor to indicate selected/highlighted tiles. """ - - def snap_to_tile(self): - """ - Snap the TileCursor to its current tile. - """ - self.rect.topleft = self.tile.rect.topleft - def act(self): - if self.tile != None: - self.snap_to_tile + def __init__(self, name, ent_id, sheet, visible = True, animation = None, animated = False, passable = True): + + # Parent initialization + super().__init__(name, ent_id, sheet, visible, animation, animated, passable) ############################################## # Section 4 - Managers for VGOs & Subclasses # @@ -150,6 +174,15 @@ class EntityManager(manager.Manager): # Entity values self.loaded_entities = pygame.sprite.Group() self.tile_cursor = None + self.total_entities = 0 # total number of unique entities loaded + + def add_entity(self, entity): + """ + Add an entity to the loaded_entities group and increment + the number of total_entities. + """ + self.loaded_entities.add(entity) + self.total_entities += 1 def load_entities_from_json(self, entsjson): """ @@ -158,23 +191,46 @@ class EntityManager(manager.Manager): j = json.load(open(os.path.join(ENTITY_JSON_PATH, entsjson))) for e in j: - self.loaded_entities.add(Entity(self.game.sheet_manager.loaded_sheets[j[e]["sheet"]], - tuple(j[e]["position"]), j[e]["visible"], + ne = Entity(j[e]["name"], self.total_entities, + self.game.sheet_manager.loaded_sheets[j[e]["sheet"]], j[e]["visible"], self.game.sheet_manager.animations[j[e]["sheet"]][j[e]["animation"]], - j[e]["animated"], j[e]["passable"], j[e]["tile"])) + j[e]["animated"], j[e]["passable"]) + ne.assign_tile(self.game.board_manager.get_tile_at_tile_pos(tuple(j[e]["tile"]))) + ne.snap_to_tile() + self.add_entity(ne) - def load_tile_cursor(self, sheet, pos = (0, 0)): + def load_tile_cursor(self, sheet): """ Load a TileCursor object to highlight selected tiles. """ - self.tile_cursor = TileCursor(self.game.sheet_manager.loaded_sheets[sheet], pos) - self.loaded_entities.add(self.tile_cursor) + self.tile_cursor = TileCursor("Tile_Cursor", self.total_entities, self.game.sheet_manager.loaded_sheets[sheet]) + self.add_entity(self.tile_cursor) + + def position_tile_cursor(self, tile_def): + """ + Snap the TileCursor object's position to 'pos' and set the + tile GID there as the current tile_cursor's selected tile. + """ + ot = (self.tile_cursor.tile_pos, self.tile_cursor.tile_gid) + self.tile_cursor.assign_tile(tile_def) + self.tile_cursor.snap_to_tile() + if ot != (self.tile_cursor.tile_pos, self.tile_cursor.tile_gid): + e = self.get_entities_by_tile(tile_def) + print(self.game.board_manager.get_tile_at_tile_pos(self.tile_cursor.tile_pos)) + if e != []: + for en in e: + print("Occupied by: " + en.name + "(" + str(en.ent_id) + ")") - def position_tile_cursor(self, pos): + def get_entities_by_tile(self, tile_def): """ - Snap the TileCursor object's position to 'pos'. + Find if there are any loaded entities at the provided tile + definition. """ - self.tile_cursor.rect.topleft = pos + found_ents = [] + for e in self.loaded_entities: + if e.tile_pos == (tile_def[0], tile_def[1]): + found_ents.append(e) + return found_ents def update_entities(self, surface = None): """