From 085446ea9389625157d41121cdbc28333a8bbb5f Mon Sep 17 00:00:00 2001 From: Marcin Kostrzewski Date: Thu, 14 May 2020 16:16:19 +0200 Subject: [PATCH] Added more documentation --- src/entities/Interactable.py | 14 +++++++++++- src/entities/Pickupable.py | 13 ++++++++++++ src/entities/Player.py | 6 ++++-- src/entities/Statistics.py | 33 +++++++++++++++++++++++++++-- src/game/EventManager.py | 20 ++++++++++++++++++ src/game/Game.py | 9 ++++++++ src/game/Map.py | 8 +++++-- src/game/Screen.py | 26 ++++++++++++++++++++++- src/game/TerrainTile.py | 10 ++++++++- src/game/Timer.py | 41 ++++++++++++++++++++++++++++++------ 10 files changed, 164 insertions(+), 16 deletions(-) diff --git a/src/entities/Interactable.py b/src/entities/Interactable.py index ed12634..f963687 100644 --- a/src/entities/Interactable.py +++ b/src/entities/Interactable.py @@ -3,12 +3,24 @@ from src.entities.Entity import Entity class Interactable(Entity): def __init__(self, texture, size, pos, Statistics): + """ + Create an interactable entity, that can be interacted with. + + :param texture: Path to a file with the texture + :param size: Size in px + :param pos: A tuple of coords (x,y) + :param Statistics: Outcome of the interaction + """ super().__init__(texture, size, pos) self.Statistics = Statistics def on_interaction(self, Player): + """ + Applies outcome to the Player + + :param Player: Player object + """ Player.statistics.set_hp(self.Statistics.hp) Player.statistics.set_stamina(self.Statistics.stamina) Player.statistics.set_thirst(self.Statistics.thirst) Player.statistics.set_hunger(self.Statistics.hunger) - diff --git a/src/entities/Pickupable.py b/src/entities/Pickupable.py index 54a9c99..477e8fc 100644 --- a/src/entities/Pickupable.py +++ b/src/entities/Pickupable.py @@ -3,9 +3,22 @@ from src.entities.Interactable import Interactable class Pickupable(Interactable): def __init__(self, texture, size, pos, Statistics): + """ + Create a pickupable object. Pickupable object disappear when interacted with. + + :param texture: Path to a file with the texture + :param size: Size in px + :param pos: Position tuple of (x,y) + :param Statistics: Outcome of the interaction + """ super().__init__(texture, size, pos, Statistics) self.is_pickupable = True def on_interaction(self, Player): + """ + Applies an outcome to the player and self-destructs. + + :param Player: Player object + """ super(Pickupable, self).on_interaction(Player) self.kill() diff --git a/src/entities/Player.py b/src/entities/Player.py index e4c2b7e..70ed5d4 100644 --- a/src/entities/Player.py +++ b/src/entities/Player.py @@ -10,7 +10,9 @@ from src.entities.Statistics import Statistics class Player(Entity): def __init__(self, spawnpoint, size): """ - :param spawnpoint: A tuple of relative coords + Create a player. + + :param spawnpoint: A tuple of coords (x,y) :param size: The size in px """ @@ -35,7 +37,7 @@ class Player(Entity): def applyWalkingFatigue(self): """ - Lowers player's statistics. + Lowers player's statistics. Applied every few steps. """ # looses hunger every 10 steps taken diff --git a/src/entities/Statistics.py b/src/entities/Statistics.py index 4c0a507..4ec45d9 100644 --- a/src/entities/Statistics.py +++ b/src/entities/Statistics.py @@ -1,12 +1,27 @@ class Statistics: def __init__(self, hp, hunger, thirst, stamina): + """ + Create a statistic object. Used to determine some object state (usually player's). + :param hp: Health points + :param hunger: Hunger (it rises) + :param thirst: Thirst (also rises) + :param stamina: Stamina points that decrease. + """ self.hp = hp self.hunger = hunger self.thirst = thirst self.stamina = stamina - # methods that don't let the values pass below 0 and over 100 during change + """ + methods that don't let the values pass below 0 and over 100 during change + """ + def set_hp(self, hp_diff): + """ + Setter method for setting HP. + + :param hp_diff: Difference as integer + """ if 0 <= self.hp + hp_diff <= 100: self.hp = self.hp + hp_diff else: @@ -16,6 +31,11 @@ class Statistics: self.hp = 100 def set_hunger(self, hunger_diff): + """ + Setter method for setting hunger points. + + :param hunger_diff: Difference as integer + """ if 0 <= self.hunger + hunger_diff <= 100: self.hunger = self.hunger + hunger_diff else: @@ -25,6 +45,11 @@ class Statistics: self.hunger = 100 def set_thirst(self, thirst_diff): + """ + Setter method for setting thirst. + + :param thirst_diff: Difference as integer + """ if 0 <= self.thirst + thirst_diff <= 100: self.thirst = self.thirst + thirst_diff else: @@ -34,6 +59,11 @@ class Statistics: self.thirst = 100 def set_stamina(self, stamina_diff): + """ + Setter method for setting stamina points. + + :param stamina_diff: Difference as integer + """ if 0 <= self.stamina + stamina_diff <= 100: self.stamina = self.stamina + stamina_diff else: @@ -41,4 +71,3 @@ class Statistics: self.stamina = 0 else: self.stamina = 100 - diff --git a/src/game/EventManager.py b/src/game/EventManager.py index 71af182..7880882 100644 --- a/src/game/EventManager.py +++ b/src/game/EventManager.py @@ -8,6 +8,12 @@ from src.entities.Enums import Movement class EventManager: def __init__(self, gameObject, player): + """ + Create a singleton EventManager to handle events like keyboard input. + + :param gameObject: Game object + :param player: The player + """ # TODO: Is this really necessary? self.game = gameObject @@ -21,6 +27,9 @@ class EventManager: pass def handleEvents(self): + """ + Called every frame. Captures keyboard input, PyGame events, updates the time and UI. + """ pygame.event.pump() if self.turnOff: @@ -51,6 +60,12 @@ class EventManager: self.game.screen.ui.updateBarsBasedOnPlayerStats(self.player.statistics) def handleClickingOnCollidablesAndTerrains(self, pos): + """ + Handles clicking on objects. Calls A* functions to move the player to the object that the mouse was + pointing to. + + :param pos: Absolute object coords as a tuple of (x,y) + """ # get a list of all collidables that are under the mouse cursor clicked_collidables = [s for s in self.game.map.collidables if s.rect.collidepoint(pos)] @@ -67,6 +82,11 @@ class EventManager: print("NO TERRAIN FOUND UNDER CLICK") def handlePlayerControls(self, keys): + """ + Handles player movement with the keyboard. + + :param keys: A list of pressed keys + """ # Key names are temporary # TODO: Load key bindings from JSON diff --git a/src/game/Game.py b/src/game/Game.py index a633b44..ca2c588 100644 --- a/src/game/Game.py +++ b/src/game/Game.py @@ -14,6 +14,12 @@ from src.game.Timer import Timer # Main Game class class Game: def __init__(self, filesPath): + """ + Game script initialization. Loads all files, creates screen, map, tiles, entities and a player. + Starts the main game loop at the end. + + :param filesPath: Absolute path to the root of the gamefiles + """ self.running = True print("Loading configuration...", end=" ") @@ -75,6 +81,9 @@ class Game: self.mainLoop() def mainLoop(self): + """ + Continuously running loop. Calls events, updates and draws everything. + """ while self.running: # Tick the timers self.ingameTimer.updateTime(self.pgTimer.tick()) diff --git a/src/game/Map.py b/src/game/Map.py index 2e9adda..e890725 100644 --- a/src/game/Map.py +++ b/src/game/Map.py @@ -11,7 +11,6 @@ from src.entities.Pickupable import Pickupable from src.entities.Statistics import Statistics -# TODO: Map should determine entities' position class Map: def __init__(self, filename, screen): """ @@ -161,7 +160,12 @@ class Map: # TODO: REMOVE DONT ADD def addEntity(self, entity, DONTADD=False): - # TODO: This method should set entities coords + """ + Adds an entity to the map. + + :param entity: Entity + :param DONTADD: ???? + """ self.screen.addSprite(entity, Locations.MAP) # dodajemy bo wszystkie entity są kolizyjne self.collidables.add(entity) diff --git a/src/game/Screen.py b/src/game/Screen.py index 6ee9c66..63445bf 100644 --- a/src/game/Screen.py +++ b/src/game/Screen.py @@ -17,6 +17,13 @@ class Locations(Enum): class Screen: def __init__(self, gameObject, windowConfig): + """ + Create a signleton screen object. + + :param gameObject: Game object + :param windowConfig: A dictionary with window settings. + :except KeyError + """ self.gameObject = gameObject self.winX = windowConfig["width"] self.winY = windowConfig["height"] @@ -36,6 +43,12 @@ class Screen: self.__initUi__() def calculateMapDimensions(self): + """ + Determines the map's dimmension based on the screen size. + The map will be shrunk down if there's not enough space for the UI. + + :return: New map size as Int + """ result = 0 expectedSize = self.winY @@ -49,7 +62,8 @@ class Screen: def addSprite(self, sprite, location): """ - Adds a sprite to a screen at a given location + Adds a sprite to a screen at a given location. + :type location: Locations :param sprite: A sprite to add. :param location: Where should the sprite be displayed @@ -66,6 +80,12 @@ class Screen: self.gameObject.spritesList.add(sprite) def getUiWidth(self, location: Locations): + """ + Gets the width of the UI. + + :param location: Specify what UI size to return + :return: Width as Int + """ if location is Locations.RIGHT_UI: return self.winX - (self.mapCoord + self.mapSize) elif location is Locations.LEFT_UI: @@ -75,6 +95,10 @@ class Screen: # TODO: Move to game / events def __initUi__(self): + """ + Creates entire UI + + """ self.ui = Ui(self.getUiWidth(Locations.RIGHT_UI), self.getUiWidth(Locations.LEFT_UI), self.winY, self.gameObject.ingameTimer) self.addSprite(self.ui.timerTextView, Locations.LEFT_UI) diff --git a/src/game/TerrainTile.py b/src/game/TerrainTile.py index 04edcc1..771ed12 100644 --- a/src/game/TerrainTile.py +++ b/src/game/TerrainTile.py @@ -5,6 +5,15 @@ import pygame # TODO: Relative coords class TerrainTile(pygame.sprite.Sprite): def __init__(self, x, y, texture, tileSize, cost): + """ + Create a tile object. + + :param x: Absolute X coord + :param y: Absolute Y coord + :param texture: Texture name found in data/images/terrain + :param tileSize: Size in px + :param cost: Cost of getting into this tile + """ super().__init__() terrainTexturesPath = Path("./data/images/terrain").resolve() self.image = pygame.image.load(str(terrainTexturesPath / texture)).convert() @@ -15,4 +24,3 @@ class TerrainTile(pygame.sprite.Sprite): self.rect.x = x * tileSize self.rect.y = y * tileSize self.cost = cost - diff --git a/src/game/Timer.py b/src/game/Timer.py index 07496c9..4ed0571 100644 --- a/src/game/Timer.py +++ b/src/game/Timer.py @@ -11,6 +11,12 @@ NIGHT_START = "22:00" class Timer: def __init__(self, startTime="12:00"): + """ + Create an in-game timer. It acts like a regular clock, but each minute is one second IRL. + The clock is not started by default. Call Timer.startClock() to make it running. + + :param startTime: Starting time as a string in the format of HH:MM, where HH is hours value, MM is minutes value + """ self.clock = pygame.time.Clock() # Time in milliseconds updated every frame, starts counting from what we specify as a parameter @@ -19,13 +25,23 @@ class Timer: self.isStarted = False def startClock(self): + """ + Start the clock. + """ self.isStarted = True def stopClock(self): + """ + Stop the clock. + """ self.isStarted = False - # Returns a string with formatted time def getPrettyTime(self): + """ + Get a pretty looking time. + + :return: String in the format of HH:MM + """ # 60 times faster than real time minutes = int(self.timePassed / 1000) % 60 hours = int(self.timePassed / 60000) % 24 @@ -41,26 +57,37 @@ class Timer: # Return a formatted time return prefixHr + str(hours) + ":" + prefixMin + str(minutes) - # Returns true, if it's daytime def isItDay(self): + """ + Get current cycle. + + :return: True, if it's daytime, otherwise False. + """ if self.timeToMs(DAY_START) < self.timePassed < self.timeToMs(NIGHT_START): return True else: return False - # Called every frame to update the timer def updateTime(self, elapsed): + """ + Should be called every frame to update the timer. + + :param elapsed: Time of the frame + """ # Only happens if the time is set to be running if self.isStarted: # Modulo, since we use the 24-hour cycle # In our case, the time loops every 24 minutes - self.timePassed =(self.timePassed + elapsed) % 1440000 + self.timePassed = (self.timePassed + elapsed) % 1440000 - # Converts time as string to integer milliseconds def timeToMs(self, timeString): + """ + Converts time from string format to milliseconds. + + :param timeString: Time string in format HH:MM + :return: Milliseconds integer + """ timeList = timeString.split(':') hours = timeList[0] minutes = timeList[1] return int(hours) * 60000 + int(minutes) * 1000 - -