Added more documentation
This commit is contained in:
parent
2b07e7394f
commit
085446ea93
@ -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)
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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())
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user