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):
|
class Interactable(Entity):
|
||||||
def __init__(self, texture, size, pos, Statistics):
|
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)
|
super().__init__(texture, size, pos)
|
||||||
self.Statistics = Statistics
|
self.Statistics = Statistics
|
||||||
|
|
||||||
def on_interaction(self, Player):
|
def on_interaction(self, Player):
|
||||||
|
"""
|
||||||
|
Applies outcome to the Player
|
||||||
|
|
||||||
|
:param Player: Player object
|
||||||
|
"""
|
||||||
Player.statistics.set_hp(self.Statistics.hp)
|
Player.statistics.set_hp(self.Statistics.hp)
|
||||||
Player.statistics.set_stamina(self.Statistics.stamina)
|
Player.statistics.set_stamina(self.Statistics.stamina)
|
||||||
Player.statistics.set_thirst(self.Statistics.thirst)
|
Player.statistics.set_thirst(self.Statistics.thirst)
|
||||||
Player.statistics.set_hunger(self.Statistics.hunger)
|
Player.statistics.set_hunger(self.Statistics.hunger)
|
||||||
|
|
||||||
|
@ -3,9 +3,22 @@ from src.entities.Interactable import Interactable
|
|||||||
|
|
||||||
class Pickupable(Interactable):
|
class Pickupable(Interactable):
|
||||||
def __init__(self, texture, size, pos, Statistics):
|
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)
|
super().__init__(texture, size, pos, Statistics)
|
||||||
self.is_pickupable = True
|
self.is_pickupable = True
|
||||||
|
|
||||||
def on_interaction(self, Player):
|
def on_interaction(self, Player):
|
||||||
|
"""
|
||||||
|
Applies an outcome to the player and self-destructs.
|
||||||
|
|
||||||
|
:param Player: Player object
|
||||||
|
"""
|
||||||
super(Pickupable, self).on_interaction(Player)
|
super(Pickupable, self).on_interaction(Player)
|
||||||
self.kill()
|
self.kill()
|
||||||
|
@ -10,7 +10,9 @@ from src.entities.Statistics import Statistics
|
|||||||
class Player(Entity):
|
class Player(Entity):
|
||||||
def __init__(self, spawnpoint, size):
|
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
|
:param size: The size in px
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -35,7 +37,7 @@ class Player(Entity):
|
|||||||
|
|
||||||
def applyWalkingFatigue(self):
|
def applyWalkingFatigue(self):
|
||||||
"""
|
"""
|
||||||
Lowers player's statistics.
|
Lowers player's statistics. Applied every few steps.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# looses hunger every 10 steps taken
|
# looses hunger every 10 steps taken
|
||||||
|
@ -1,12 +1,27 @@
|
|||||||
class Statistics:
|
class Statistics:
|
||||||
def __init__(self, hp, hunger, thirst, stamina):
|
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.hp = hp
|
||||||
self.hunger = hunger
|
self.hunger = hunger
|
||||||
self.thirst = thirst
|
self.thirst = thirst
|
||||||
self.stamina = stamina
|
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):
|
def set_hp(self, hp_diff):
|
||||||
|
"""
|
||||||
|
Setter method for setting HP.
|
||||||
|
|
||||||
|
:param hp_diff: Difference as integer
|
||||||
|
"""
|
||||||
if 0 <= self.hp + hp_diff <= 100:
|
if 0 <= self.hp + hp_diff <= 100:
|
||||||
self.hp = self.hp + hp_diff
|
self.hp = self.hp + hp_diff
|
||||||
else:
|
else:
|
||||||
@ -16,6 +31,11 @@ class Statistics:
|
|||||||
self.hp = 100
|
self.hp = 100
|
||||||
|
|
||||||
def set_hunger(self, hunger_diff):
|
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:
|
if 0 <= self.hunger + hunger_diff <= 100:
|
||||||
self.hunger = self.hunger + hunger_diff
|
self.hunger = self.hunger + hunger_diff
|
||||||
else:
|
else:
|
||||||
@ -25,6 +45,11 @@ class Statistics:
|
|||||||
self.hunger = 100
|
self.hunger = 100
|
||||||
|
|
||||||
def set_thirst(self, thirst_diff):
|
def set_thirst(self, thirst_diff):
|
||||||
|
"""
|
||||||
|
Setter method for setting thirst.
|
||||||
|
|
||||||
|
:param thirst_diff: Difference as integer
|
||||||
|
"""
|
||||||
if 0 <= self.thirst + thirst_diff <= 100:
|
if 0 <= self.thirst + thirst_diff <= 100:
|
||||||
self.thirst = self.thirst + thirst_diff
|
self.thirst = self.thirst + thirst_diff
|
||||||
else:
|
else:
|
||||||
@ -34,6 +59,11 @@ class Statistics:
|
|||||||
self.thirst = 100
|
self.thirst = 100
|
||||||
|
|
||||||
def set_stamina(self, stamina_diff):
|
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:
|
if 0 <= self.stamina + stamina_diff <= 100:
|
||||||
self.stamina = self.stamina + stamina_diff
|
self.stamina = self.stamina + stamina_diff
|
||||||
else:
|
else:
|
||||||
@ -41,4 +71,3 @@ class Statistics:
|
|||||||
self.stamina = 0
|
self.stamina = 0
|
||||||
else:
|
else:
|
||||||
self.stamina = 100
|
self.stamina = 100
|
||||||
|
|
||||||
|
@ -8,6 +8,12 @@ from src.entities.Enums import Movement
|
|||||||
|
|
||||||
class EventManager:
|
class EventManager:
|
||||||
def __init__(self, gameObject, player):
|
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?
|
# TODO: Is this really necessary?
|
||||||
self.game = gameObject
|
self.game = gameObject
|
||||||
|
|
||||||
@ -21,6 +27,9 @@ class EventManager:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def handleEvents(self):
|
def handleEvents(self):
|
||||||
|
"""
|
||||||
|
Called every frame. Captures keyboard input, PyGame events, updates the time and UI.
|
||||||
|
"""
|
||||||
pygame.event.pump()
|
pygame.event.pump()
|
||||||
|
|
||||||
if self.turnOff:
|
if self.turnOff:
|
||||||
@ -51,6 +60,12 @@ class EventManager:
|
|||||||
self.game.screen.ui.updateBarsBasedOnPlayerStats(self.player.statistics)
|
self.game.screen.ui.updateBarsBasedOnPlayerStats(self.player.statistics)
|
||||||
|
|
||||||
def handleClickingOnCollidablesAndTerrains(self, pos):
|
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
|
# 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)]
|
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")
|
print("NO TERRAIN FOUND UNDER CLICK")
|
||||||
|
|
||||||
def handlePlayerControls(self, keys):
|
def handlePlayerControls(self, keys):
|
||||||
|
"""
|
||||||
|
Handles player movement with the keyboard.
|
||||||
|
|
||||||
|
:param keys: A list of pressed keys
|
||||||
|
"""
|
||||||
# Key names are temporary
|
# Key names are temporary
|
||||||
# TODO: Load key bindings from JSON
|
# TODO: Load key bindings from JSON
|
||||||
|
|
||||||
|
@ -14,6 +14,12 @@ from src.game.Timer import Timer
|
|||||||
# Main Game class
|
# Main Game class
|
||||||
class Game:
|
class Game:
|
||||||
def __init__(self, filesPath):
|
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
|
self.running = True
|
||||||
print("Loading configuration...", end=" ")
|
print("Loading configuration...", end=" ")
|
||||||
|
|
||||||
@ -75,6 +81,9 @@ class Game:
|
|||||||
self.mainLoop()
|
self.mainLoop()
|
||||||
|
|
||||||
def mainLoop(self):
|
def mainLoop(self):
|
||||||
|
"""
|
||||||
|
Continuously running loop. Calls events, updates and draws everything.
|
||||||
|
"""
|
||||||
while self.running:
|
while self.running:
|
||||||
# Tick the timers
|
# Tick the timers
|
||||||
self.ingameTimer.updateTime(self.pgTimer.tick())
|
self.ingameTimer.updateTime(self.pgTimer.tick())
|
||||||
|
@ -11,7 +11,6 @@ from src.entities.Pickupable import Pickupable
|
|||||||
from src.entities.Statistics import Statistics
|
from src.entities.Statistics import Statistics
|
||||||
|
|
||||||
|
|
||||||
# TODO: Map should determine entities' position
|
|
||||||
class Map:
|
class Map:
|
||||||
def __init__(self, filename, screen):
|
def __init__(self, filename, screen):
|
||||||
"""
|
"""
|
||||||
@ -161,7 +160,12 @@ class Map:
|
|||||||
|
|
||||||
# TODO: REMOVE DONT ADD
|
# TODO: REMOVE DONT ADD
|
||||||
def addEntity(self, entity, DONTADD=False):
|
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)
|
self.screen.addSprite(entity, Locations.MAP)
|
||||||
# dodajemy bo wszystkie entity są kolizyjne
|
# dodajemy bo wszystkie entity są kolizyjne
|
||||||
self.collidables.add(entity)
|
self.collidables.add(entity)
|
||||||
|
@ -17,6 +17,13 @@ class Locations(Enum):
|
|||||||
|
|
||||||
class Screen:
|
class Screen:
|
||||||
def __init__(self, gameObject, windowConfig):
|
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.gameObject = gameObject
|
||||||
self.winX = windowConfig["width"]
|
self.winX = windowConfig["width"]
|
||||||
self.winY = windowConfig["height"]
|
self.winY = windowConfig["height"]
|
||||||
@ -36,6 +43,12 @@ class Screen:
|
|||||||
self.__initUi__()
|
self.__initUi__()
|
||||||
|
|
||||||
def calculateMapDimensions(self):
|
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
|
result = 0
|
||||||
expectedSize = self.winY
|
expectedSize = self.winY
|
||||||
|
|
||||||
@ -49,7 +62,8 @@ class Screen:
|
|||||||
|
|
||||||
def addSprite(self, sprite, location):
|
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
|
:type location: Locations
|
||||||
:param sprite: A sprite to add.
|
:param sprite: A sprite to add.
|
||||||
:param location: Where should the sprite be displayed
|
:param location: Where should the sprite be displayed
|
||||||
@ -66,6 +80,12 @@ class Screen:
|
|||||||
self.gameObject.spritesList.add(sprite)
|
self.gameObject.spritesList.add(sprite)
|
||||||
|
|
||||||
def getUiWidth(self, location: Locations):
|
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:
|
if location is Locations.RIGHT_UI:
|
||||||
return self.winX - (self.mapCoord + self.mapSize)
|
return self.winX - (self.mapCoord + self.mapSize)
|
||||||
elif location is Locations.LEFT_UI:
|
elif location is Locations.LEFT_UI:
|
||||||
@ -75,6 +95,10 @@ class Screen:
|
|||||||
|
|
||||||
# TODO: Move to game / events
|
# TODO: Move to game / events
|
||||||
def __initUi__(self):
|
def __initUi__(self):
|
||||||
|
"""
|
||||||
|
Creates entire UI
|
||||||
|
|
||||||
|
"""
|
||||||
self.ui = Ui(self.getUiWidth(Locations.RIGHT_UI), self.getUiWidth(Locations.LEFT_UI), self.winY,
|
self.ui = Ui(self.getUiWidth(Locations.RIGHT_UI), self.getUiWidth(Locations.LEFT_UI), self.winY,
|
||||||
self.gameObject.ingameTimer)
|
self.gameObject.ingameTimer)
|
||||||
self.addSprite(self.ui.timerTextView, Locations.LEFT_UI)
|
self.addSprite(self.ui.timerTextView, Locations.LEFT_UI)
|
||||||
|
@ -5,6 +5,15 @@ import pygame
|
|||||||
# TODO: Relative coords
|
# TODO: Relative coords
|
||||||
class TerrainTile(pygame.sprite.Sprite):
|
class TerrainTile(pygame.sprite.Sprite):
|
||||||
def __init__(self, x, y, texture, tileSize, cost):
|
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__()
|
super().__init__()
|
||||||
terrainTexturesPath = Path("./data/images/terrain").resolve()
|
terrainTexturesPath = Path("./data/images/terrain").resolve()
|
||||||
self.image = pygame.image.load(str(terrainTexturesPath / texture)).convert()
|
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.x = x * tileSize
|
||||||
self.rect.y = y * tileSize
|
self.rect.y = y * tileSize
|
||||||
self.cost = cost
|
self.cost = cost
|
||||||
|
|
||||||
|
@ -11,6 +11,12 @@ NIGHT_START = "22:00"
|
|||||||
|
|
||||||
class Timer:
|
class Timer:
|
||||||
def __init__(self, startTime="12:00"):
|
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()
|
self.clock = pygame.time.Clock()
|
||||||
|
|
||||||
# Time in milliseconds updated every frame, starts counting from what we specify as a parameter
|
# Time in milliseconds updated every frame, starts counting from what we specify as a parameter
|
||||||
@ -19,13 +25,23 @@ class Timer:
|
|||||||
self.isStarted = False
|
self.isStarted = False
|
||||||
|
|
||||||
def startClock(self):
|
def startClock(self):
|
||||||
|
"""
|
||||||
|
Start the clock.
|
||||||
|
"""
|
||||||
self.isStarted = True
|
self.isStarted = True
|
||||||
|
|
||||||
def stopClock(self):
|
def stopClock(self):
|
||||||
|
"""
|
||||||
|
Stop the clock.
|
||||||
|
"""
|
||||||
self.isStarted = False
|
self.isStarted = False
|
||||||
|
|
||||||
# Returns a string with formatted time
|
|
||||||
def getPrettyTime(self):
|
def getPrettyTime(self):
|
||||||
|
"""
|
||||||
|
Get a pretty looking time.
|
||||||
|
|
||||||
|
:return: String in the format of HH:MM
|
||||||
|
"""
|
||||||
# 60 times faster than real time
|
# 60 times faster than real time
|
||||||
minutes = int(self.timePassed / 1000) % 60
|
minutes = int(self.timePassed / 1000) % 60
|
||||||
hours = int(self.timePassed / 60000) % 24
|
hours = int(self.timePassed / 60000) % 24
|
||||||
@ -41,26 +57,37 @@ class Timer:
|
|||||||
# Return a formatted time
|
# Return a formatted time
|
||||||
return prefixHr + str(hours) + ":" + prefixMin + str(minutes)
|
return prefixHr + str(hours) + ":" + prefixMin + str(minutes)
|
||||||
|
|
||||||
# Returns true, if it's daytime
|
|
||||||
def isItDay(self):
|
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):
|
if self.timeToMs(DAY_START) < self.timePassed < self.timeToMs(NIGHT_START):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Called every frame to update the timer
|
|
||||||
def updateTime(self, elapsed):
|
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
|
# Only happens if the time is set to be running
|
||||||
if self.isStarted:
|
if self.isStarted:
|
||||||
# Modulo, since we use the 24-hour cycle
|
# Modulo, since we use the 24-hour cycle
|
||||||
# In our case, the time loops every 24 minutes
|
# 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):
|
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(':')
|
timeList = timeString.split(':')
|
||||||
hours = timeList[0]
|
hours = timeList[0]
|
||||||
minutes = timeList[1]
|
minutes = timeList[1]
|
||||||
return int(hours) * 60000 + int(minutes) * 1000
|
return int(hours) * 60000 + int(minutes) * 1000
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user