Compare commits
15 Commits
master
...
UI_staticP
Author | SHA1 | Date | |
---|---|---|---|
|
21ea6cf1de | ||
|
085beb263a | ||
|
9fa6da8e8e | ||
|
8df653bacf | ||
|
741222e0aa | ||
|
7bf924e2c9 | ||
|
8c479be091 | ||
|
b606124d38 | ||
|
786db30b58 | ||
|
25903c2126 | ||
|
f0d6f5f8e4 | ||
|
d2f7cbc6ed | ||
|
82eb2b9857 | ||
|
bdcc564ebb | ||
|
3a028da28f |
118
src/ui/Ui.py
118
src/ui/Ui.py
@ -1,39 +1,52 @@
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
|
|
||||||
from src.entities.Enums import StatisticNames
|
from src.entities.Enums import StatisticNames
|
||||||
|
from src.entities.Interactable import Interactable
|
||||||
|
from src.entities.Pickupable import Pickupable
|
||||||
|
from src.entities.Player import Player
|
||||||
from src.entities.Statistics import Statistics
|
from src.entities.Statistics import Statistics
|
||||||
|
from src.game.Timer import Timer
|
||||||
from src.ui.UiBar import UiBar
|
from src.ui.UiBar import UiBar
|
||||||
from src.ui.UiConsole import UiConsole
|
from src.ui.UiConsole import UiConsole
|
||||||
from src.ui.UiText import UiText
|
from src.ui.UiText import UiText
|
||||||
|
|
||||||
|
|
||||||
class Ui():
|
class Ui:
|
||||||
def __init__(self, rightUiWidth, leftUiWidth, screenHeight, timer, font=None, antialias=True):
|
elements: pygame.sprite.Group
|
||||||
|
timer: Timer
|
||||||
|
antialias: bool
|
||||||
|
barHeight: float
|
||||||
|
|
||||||
|
def __init__(self, rightUiWidth: int, leftUiWidth: int, screenHeight: int, timer: Timer,
|
||||||
|
font: Union[pygame.font.Font, None] = None, antialias: bool = True):
|
||||||
|
"""
|
||||||
|
Creates Ui object. Instantiates all UI elements.
|
||||||
|
|
||||||
|
:param rightUiWidth:
|
||||||
|
:param leftUiWidth:
|
||||||
|
:param screenHeight:
|
||||||
|
:param timer:
|
||||||
|
:param font:
|
||||||
|
:param antialias:
|
||||||
|
"""
|
||||||
self.elements = pygame.sprite.Group()
|
self.elements = pygame.sprite.Group()
|
||||||
|
|
||||||
self.leftUiWidth = leftUiWidth
|
self.leftUiWidth = leftUiWidth
|
||||||
self.rightUiWidth = rightUiWidth
|
self.rightUiWidth = rightUiWidth
|
||||||
self.screenHeight = screenHeight
|
self.screenHeight = screenHeight
|
||||||
|
|
||||||
|
# Default bar's height, like hp bar.
|
||||||
self.barHeight = 25
|
self.barHeight = 25
|
||||||
|
|
||||||
self.antialias = antialias
|
self.antialias = antialias
|
||||||
|
|
||||||
fontName = "FiraCode-Light.ttf"
|
# If no font was given then load it from predefined file.
|
||||||
fontFolder = ""
|
|
||||||
fontFile = ""
|
|
||||||
try:
|
|
||||||
fontFolder = Path("./data/fonts")
|
|
||||||
fontFile = fontFolder / fontName
|
|
||||||
except IOError:
|
|
||||||
print("Cannot load texture from " + fontFolder + ". Exiting...")
|
|
||||||
exit(1)
|
|
||||||
fontPath = str(fontFile.resolve())
|
|
||||||
if font is None:
|
if font is None:
|
||||||
font = pygame.font.Font(fontPath, int(self.barHeight / 1.5))
|
font = self.__loadFont__()
|
||||||
self.font = font
|
self.font = font
|
||||||
|
|
||||||
self.timer = timer
|
self.timer = timer
|
||||||
@ -76,34 +89,90 @@ class Ui():
|
|||||||
screenHeight - self.timerTextView.rect.h - self.isDayTextView.rect.h),
|
screenHeight - self.timerTextView.rect.h - self.isDayTextView.rect.h),
|
||||||
font=self.font, antialias=self.antialias)
|
font=self.font, antialias=self.antialias)
|
||||||
|
|
||||||
|
def __loadFont__(self) -> pygame.font.Font:
|
||||||
|
"""
|
||||||
|
Loads project's default font.
|
||||||
|
|
||||||
|
:return: Font loaded from file.
|
||||||
|
"""
|
||||||
|
fontName = "FiraCode-Light.ttf"
|
||||||
|
fontFolder = ""
|
||||||
|
fontFile = ""
|
||||||
|
try:
|
||||||
|
fontFolder = Path("./data/fonts")
|
||||||
|
fontFile = fontFolder / fontName
|
||||||
|
except IOError:
|
||||||
|
print("Cannot load font from " + fontFolder + ". Exiting...")
|
||||||
|
exit(1)
|
||||||
|
fontPath = str(fontFile.resolve())
|
||||||
|
font = pygame.font.Font(fontPath, int(self.barHeight / 1.5))
|
||||||
|
return font
|
||||||
|
|
||||||
def updateConsoleBasedOnPlayerStats(self, statistics: Statistics):
|
def updateConsoleBasedOnPlayerStats(self, statistics: Statistics):
|
||||||
|
"""
|
||||||
|
Prints statistics on console.
|
||||||
|
|
||||||
|
:param statistics: Statistics to print
|
||||||
|
"""
|
||||||
consoleLines = ["Health: " + str(statistics.hp), "Hunger: " + str(statistics.hunger),
|
consoleLines = ["Health: " + str(statistics.hp), "Hunger: " + str(statistics.hunger),
|
||||||
"Stamina: " + str(statistics.stamina), "Thirst: " + str(statistics.thirst)]
|
"Stamina: " + str(statistics.stamina), "Thirst: " + str(statistics.thirst)]
|
||||||
self.console.addLinesToConsoleAndScrollToDisplayThem(consoleLines)
|
|
||||||
|
for line in consoleLines:
|
||||||
|
self.console.printToConsole(line)
|
||||||
|
|
||||||
def updateBarsBasedOnPlayerStats(self, statistics: Statistics):
|
def updateBarsBasedOnPlayerStats(self, statistics: Statistics):
|
||||||
|
"""
|
||||||
|
Updates bars like hp bar to match player's statistics.
|
||||||
|
|
||||||
|
:param statistics:
|
||||||
|
"""
|
||||||
self.healthBar.updateFill(statistics.hp)
|
self.healthBar.updateFill(statistics.hp)
|
||||||
self.hungerBar.updateFill(statistics.hunger)
|
self.hungerBar.updateFill(statistics.hunger)
|
||||||
self.staminaBar.updateFill(statistics.stamina)
|
self.staminaBar.updateFill(statistics.stamina)
|
||||||
self.thirstBar.updateFill(statistics.thirst)
|
self.thirstBar.updateFill(statistics.thirst)
|
||||||
|
|
||||||
def updateBasedOnPygameEvent(self, event: pygame.event):
|
def updateBasedOnPygameEvent(self, event: pygame.event):
|
||||||
|
"""
|
||||||
|
Examines event and does actions:
|
||||||
|
- console scrolling
|
||||||
|
|
||||||
|
:param event: pygame event to examine.
|
||||||
|
"""
|
||||||
if event.type == pygame.MOUSEBUTTONDOWN:
|
if event.type == pygame.MOUSEBUTTONDOWN:
|
||||||
console = self.console
|
console = self.console
|
||||||
if event.button == 4:
|
if event.button == 4:
|
||||||
console.writeConsoleLines(console.topWrittenLineInd + 1)
|
console.scrollDown()
|
||||||
elif event.button == 5:
|
elif event.button == 5:
|
||||||
console.writeConsoleLines(console.topWrittenLineInd - 1)
|
console.scrollUp()
|
||||||
|
|
||||||
def updateOnPlayerPickup(self, playerStats, pickedObject):
|
def updateOnPlayerPickup(self, playerStats, pickedObject: Pickupable):
|
||||||
self.console.addLinesToConsoleAndScrollToDisplayThem([self.timer.getPrettyTime() + " - Picked object " + str(pickedObject.id) + ":"])
|
"""
|
||||||
|
This method should be called to update UI state after player pickup.
|
||||||
|
Given player statistics and picked object updates bars and prints message to console.
|
||||||
|
|
||||||
|
:param playerStats:
|
||||||
|
:param pickedObject:
|
||||||
|
"""
|
||||||
|
self.console.printToConsole(self.timer.getPrettyTime() + " - Picked object " + str(pickedObject.id) + ":")
|
||||||
self.updateConsoleBasedOnPlayerStats(playerStats)
|
self.updateConsoleBasedOnPlayerStats(playerStats)
|
||||||
|
|
||||||
def updateOnPlayerInteraction(self, playerStats, interactedObject):
|
def updateOnPlayerInteraction(self, playerStats, interactedObject: Interactable):
|
||||||
self.console.addLinesToConsoleAndScrollToDisplayThem([self.timer.getPrettyTime() + " - Player interacted with " + str(interactedObject.id) + ":"])
|
"""
|
||||||
|
This method should be called to update UI state after player interaction.
|
||||||
|
Updates bars and prints message to console.
|
||||||
|
|
||||||
|
:param playerStats:
|
||||||
|
:param interactedObject:
|
||||||
|
"""
|
||||||
|
self.console.printToConsole(self.timer.getPrettyTime() + " - Player interacted with " + str(interactedObject.id) + ":")
|
||||||
self.updateConsoleBasedOnPlayerStats(playerStats)
|
self.updateConsoleBasedOnPlayerStats(playerStats)
|
||||||
|
|
||||||
def updateOnDeath(self, player):
|
def updateOnDeath(self, player: Player):
|
||||||
|
"""
|
||||||
|
Updates UI after player death. Prints death reason to console.
|
||||||
|
|
||||||
|
:param player: Dead player.
|
||||||
|
"""
|
||||||
consoleLines = []
|
consoleLines = []
|
||||||
|
|
||||||
deathReason: StatisticNames = player.deathReason
|
deathReason: StatisticNames = player.deathReason
|
||||||
@ -123,9 +192,14 @@ class Ui():
|
|||||||
|
|
||||||
consoleLines.append("Time alive: " + str(player.timeAlive / 1000) + "s")
|
consoleLines.append("Time alive: " + str(player.timeAlive / 1000) + "s")
|
||||||
|
|
||||||
self.console.addLinesToConsoleAndScrollToDisplayThem(consoleLines)
|
for line in consoleLines:
|
||||||
|
self.console.printToConsole(line)
|
||||||
|
|
||||||
def updateTime(self):
|
def updateTime(self):
|
||||||
|
"""
|
||||||
|
Updates timer and changes text eventually changes day or night text.
|
||||||
|
|
||||||
|
"""
|
||||||
self.timerTextView.changeText(self.timer.getPrettyTime())
|
self.timerTextView.changeText(self.timer.getPrettyTime())
|
||||||
if self.timer.isItDay():
|
if self.timer.isItDay():
|
||||||
self.isDayTextView.changeText("Day")
|
self.isDayTextView.changeText("Day")
|
||||||
|
@ -1,32 +1,62 @@
|
|||||||
|
from typing import Tuple
|
||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
|
|
||||||
from src.ui.UiElement import UiElement
|
from src.ui.UiElement import UiElement
|
||||||
|
|
||||||
|
|
||||||
class UiBar(UiElement):
|
class UiBar(UiElement):
|
||||||
def __init__(self, rect: pygame.Rect, initialFilledPercent=100, filledBarColor=(255, 0, 0), emptyBarColor=(0, 0, 0),
|
filledBarColor: Tuple[int, int, int]
|
||||||
outlineColor=(75, 75, 75), outlineThickness=10):
|
outlineThickness: int
|
||||||
|
outlineColor: Tuple[int, int, int]
|
||||||
|
emptyBarColor: Tuple[int, int, int]
|
||||||
|
filledPercent: int
|
||||||
|
|
||||||
|
def __init__(self, rect: pygame.Rect, initialFilledPercent: int = 100,
|
||||||
|
filledBarColor: Tuple[int, int, int] = (255, 0, 0), emptyBarColor: Tuple[int, int, int] = (0, 0, 0),
|
||||||
|
outlineColor: Tuple[int, int, int] = (75, 75, 75), outlineThickness: int = 10):
|
||||||
|
"""
|
||||||
|
Creates UiBar object
|
||||||
|
:param rect:
|
||||||
|
:param initialFilledPercent: How much bar is filled at the beginning. Number between 0 and 100
|
||||||
|
:param filledBarColor: Color of the filled part of the bar.
|
||||||
|
:param emptyBarColor: Color of the empty part of the bar.
|
||||||
|
:param outlineColor: Color of the bar outline.
|
||||||
|
:param outlineThickness:
|
||||||
|
"""
|
||||||
super().__init__(rect)
|
super().__init__(rect)
|
||||||
self.filledPercent = initialFilledPercent / 100
|
|
||||||
|
# Make sure that filled percent is between 0 and 100
|
||||||
|
if initialFilledPercent < 0:
|
||||||
|
initialFilledPercent = 0
|
||||||
|
elif initialFilledPercent > 100:
|
||||||
|
initialFilledPercent = 100
|
||||||
|
self.filledPercent = initialFilledPercent
|
||||||
|
|
||||||
self.emptyBarColor = emptyBarColor
|
self.emptyBarColor = emptyBarColor
|
||||||
self.barColor = filledBarColor
|
self.barColor = filledBarColor
|
||||||
self.outlineColor = outlineColor
|
self.outlineColor = outlineColor
|
||||||
self.outlineThickness = outlineThickness
|
self.outlineThickness = outlineThickness
|
||||||
self.filledBarColor = filledBarColor
|
self.filledBarColor = filledBarColor
|
||||||
self.value = initialFilledPercent
|
|
||||||
|
|
||||||
self.__genBar__()
|
self.__genBar__()
|
||||||
|
|
||||||
def __genBar__(self):
|
def __genBar__(self):
|
||||||
|
"""
|
||||||
|
Generates bar image based on filled percent field.
|
||||||
|
"""
|
||||||
self.image = pygame.Surface((self.rect.width, self.rect.height))
|
self.image = pygame.Surface((self.rect.width, self.rect.height))
|
||||||
filledPartRect = pygame.rect.Rect(self.outlineThickness / 2, self.outlineThickness / 2,
|
filledPartRect = pygame.rect.Rect(self.outlineThickness / 2, self.outlineThickness / 2,
|
||||||
(self.rect.width - self.outlineThickness) * self.filledPercent,
|
(self.rect.width - self.outlineThickness) * (self.filledPercent / 100),
|
||||||
self.rect.height - self.outlineThickness)
|
self.rect.height - self.outlineThickness)
|
||||||
self.image.fill(self.filledBarColor, filledPartRect)
|
self.image.fill(self.filledBarColor, filledPartRect)
|
||||||
pygame.draw.rect(self.image, self.outlineColor, pygame.rect.Rect(0, 0, self.rect.width, self.rect.height),
|
pygame.draw.rect(self.image, self.outlineColor, pygame.rect.Rect(0, 0, self.rect.width, self.rect.height),
|
||||||
self.outlineThickness)
|
self.outlineThickness)
|
||||||
|
|
||||||
def updateFill(self, filledPercent):
|
def updateFill(self, filledPercent: int):
|
||||||
self.filledPercent = filledPercent / 100
|
"""
|
||||||
self.value = filledPercent
|
Updates how much bar is filled
|
||||||
|
:param filledPercent: Value between 0 and 100
|
||||||
|
"""
|
||||||
|
self.filledPercent = filledPercent
|
||||||
self.__genBar__()
|
self.__genBar__()
|
||||||
|
@ -1,15 +1,36 @@
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
from typing import Tuple, List, Any, Callable
|
||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
|
from pygame.font import FontType
|
||||||
|
|
||||||
from src.ui.UiElement import UiElement
|
from src.ui.UiElement import UiElement
|
||||||
|
|
||||||
|
|
||||||
class UiButton(UiElement):
|
class UiButton(UiElement):
|
||||||
|
|
||||||
def __init__(self, rect: pygame.Rect, notClickedBtnColor=(125, 125, 125), clickedBtnColor=(255, 255, 255),
|
functionsToInvokeWhenClicked: List[Tuple[Callable, Any]]
|
||||||
text="Click", textColor=(0, 0, 0), font=None, functionsToInvokeWhenClicked=[]):
|
image: pygame.Surface
|
||||||
|
beingClicked: bool
|
||||||
|
text: str
|
||||||
|
clickedBtnColor: Tuple[int, int, int]
|
||||||
|
textColor: Tuple[int, int, int]
|
||||||
|
font: pygame.font.Font
|
||||||
|
|
||||||
|
def __init__(self, rect: pygame.Rect, notClickedBtnColor: Tuple[int, int, int] = (125, 125, 125),
|
||||||
|
clickedBtnColor: Tuple[int, int, int] = (255, 255, 255),
|
||||||
|
text: str = "Click", textColor: Tuple[int, int, int] = (0, 0, 0), font: pygame.font.Font = None,
|
||||||
|
functionsToInvokeWhenClicked: List[Tuple[Callable, Any]] = []):
|
||||||
"""
|
"""
|
||||||
:type functionsToInvokeWhenClicked : list of tuple(function, args*), args are function arguments
|
Creates UiButton object.
|
||||||
|
|
||||||
|
:param rect: Rectangle on which button will be displayed.
|
||||||
|
:param notClickedBtnColor: Button color when it is not clicked.
|
||||||
|
:param clickedBtnColor: Button color when it is clicked.
|
||||||
|
:param text: Text to be displayed on button.
|
||||||
|
:param textColor:
|
||||||
|
:param font: Font for button text. If None is given then default font will be used.
|
||||||
|
:type functionsToInvokeWhenClicked : list of tuple(function, args*), args are function arguments.
|
||||||
"""
|
"""
|
||||||
super().__init__(rect)
|
super().__init__(rect)
|
||||||
if font is None:
|
if font is None:
|
||||||
@ -28,8 +49,14 @@ class UiButton(UiElement):
|
|||||||
|
|
||||||
self.functionsToInvokeWhenClicked.extend(functionsToInvokeWhenClicked)
|
self.functionsToInvokeWhenClicked.extend(functionsToInvokeWhenClicked)
|
||||||
|
|
||||||
def eventHandler(self, event):
|
def eventHandler(self, event: pygame.event):
|
||||||
# change selected color if rectangle clicked
|
"""
|
||||||
|
Checks if this button was clicked based on given pygame event.
|
||||||
|
If yes, then it calls all functions that are on the list of functions to invoke.
|
||||||
|
|
||||||
|
:param event: pygame event, which will be examined to check if this button was clicked.
|
||||||
|
"""
|
||||||
|
# change selected color if this button's rectangle was clicked
|
||||||
if event.type == pygame.MOUSEBUTTONDOWN:
|
if event.type == pygame.MOUSEBUTTONDOWN:
|
||||||
if event.button == 1:
|
if event.button == 1:
|
||||||
if self.rect.collidepoint(event.pos): # is mouse over button
|
if self.rect.collidepoint(event.pos): # is mouse over button
|
||||||
@ -42,7 +69,11 @@ class UiButton(UiElement):
|
|||||||
self.beingClicked = False
|
self.beingClicked = False
|
||||||
self.image = self._images[ButtonImages.DEFAULT_IMAGE.value]
|
self.image = self._images[ButtonImages.DEFAULT_IMAGE.value]
|
||||||
|
|
||||||
def __initBtnImages__(self):
|
def __initBtnImages__(self) -> None:
|
||||||
|
"""
|
||||||
|
Creates button images which will be drawn, so that button is displayed.
|
||||||
|
|
||||||
|
"""
|
||||||
self._images = [
|
self._images = [
|
||||||
pygame.Surface((self.rect.width, self.rect.height)),
|
pygame.Surface((self.rect.width, self.rect.height)),
|
||||||
pygame.Surface((self.rect.width, self.rect.height)),
|
pygame.Surface((self.rect.width, self.rect.height)),
|
||||||
@ -55,13 +86,21 @@ class UiButton(UiElement):
|
|||||||
self._images[0].blit(self.textSurface, self.textSurfaceDest)
|
self._images[0].blit(self.textSurface, self.textSurfaceDest)
|
||||||
self._images[1].blit(self.textSurface, self.textSurfaceDest)
|
self._images[1].blit(self.textSurface, self.textSurfaceDest)
|
||||||
|
|
||||||
def addFuncToInvoke(self, tupleOfFuncAndArgs):
|
def addFuncToInvoke(self, tupleOfFuncAndArgs: Tuple[Callable, Any]) -> None:
|
||||||
"""
|
"""
|
||||||
|
Adds given function to list of functions, which will be invoked when this button is clicked.
|
||||||
|
|
||||||
:type tupleOfFuncAndArgs: tuple(function, *args)
|
:type tupleOfFuncAndArgs: tuple(function, *args)
|
||||||
"""
|
"""
|
||||||
self.functionsToInvokeWhenClicked.append(tupleOfFuncAndArgs)
|
self.functionsToInvokeWhenClicked.append(tupleOfFuncAndArgs)
|
||||||
|
|
||||||
|
|
||||||
class ButtonImages(Enum):
|
class ButtonImages(Enum):
|
||||||
|
"""
|
||||||
|
This enum is used to display proper button images.
|
||||||
|
When button is not clicked, then default image is being drawn.
|
||||||
|
When button is clicked, clicking image is being drawn.
|
||||||
|
"""
|
||||||
|
|
||||||
DEFAULT_IMAGE = 0
|
DEFAULT_IMAGE = 0
|
||||||
CLICKING_IMAGE = 1
|
CLICKING_IMAGE = 1
|
||||||
|
@ -1,10 +1,49 @@
|
|||||||
import pygame
|
import pygame
|
||||||
|
from typing import Tuple, List
|
||||||
|
from pygame.font import FontType
|
||||||
|
|
||||||
from src.ui.UiElement import UiElement
|
from src.ui.UiElement import UiElement
|
||||||
|
|
||||||
|
|
||||||
class UiConsole(UiElement):
|
class UiConsole(UiElement):
|
||||||
def __init__(self, rect: pygame.Rect, bgColor=(125, 125, 125), textColor=(255, 255, 255), font=None, antialias=True):
|
linesCount: int
|
||||||
|
antialias: bool
|
||||||
|
bgColor: Tuple[int, int, int]
|
||||||
|
font: pygame.font.Font
|
||||||
|
maxLines: int
|
||||||
|
lineHeight: int
|
||||||
|
linesImages: List[pygame.Surface]
|
||||||
|
topWrittenLineInd: int
|
||||||
|
consoleLines: List[str]
|
||||||
|
linesImagesCount: int
|
||||||
|
consoleWidth: float
|
||||||
|
image: pygame.Surface
|
||||||
|
|
||||||
|
# Static field, with every update() call strings from buffer are written to the console. See printToConsole()
|
||||||
|
buffer: List[str] = []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def printToConsole(inp: str):
|
||||||
|
"""
|
||||||
|
Adds given string to buffer. Everything from buffer will be written to console when update() will be called.
|
||||||
|
update() is called every frame.
|
||||||
|
|
||||||
|
:param inp: String to be written to console.
|
||||||
|
"""
|
||||||
|
UiConsole.buffer.append(inp)
|
||||||
|
|
||||||
|
def __init__(self, rect: pygame.Rect, bgColor: Tuple[int, int, int] = (125, 125, 125),
|
||||||
|
textColor: Tuple[int, int, int] = (255, 255, 255), font: pygame.font.Font = None,
|
||||||
|
antialias: bool = True):
|
||||||
|
"""
|
||||||
|
Creates UiConsole object.
|
||||||
|
|
||||||
|
:param rect: Rectangle on which console will be drawn.
|
||||||
|
:param bgColor:
|
||||||
|
:param textColor:
|
||||||
|
:param font: Defaults to None, then default pygame font will be used.
|
||||||
|
:param antialias:
|
||||||
|
"""
|
||||||
super().__init__(rect)
|
super().__init__(rect)
|
||||||
self.textColor = textColor
|
self.textColor = textColor
|
||||||
|
|
||||||
@ -30,9 +69,46 @@ class UiConsole(UiElement):
|
|||||||
self.maxLines = int(self.image.get_height() / self.lineHeight)
|
self.maxLines = int(self.image.get_height() / self.lineHeight)
|
||||||
|
|
||||||
self.addLinesToConsole(["Hello from console!"])
|
self.addLinesToConsole(["Hello from console!"])
|
||||||
self.writeConsoleLines()
|
self.__writeConsoleLines__()
|
||||||
|
|
||||||
def writeConsoleLines(self, startingLineInd=0):
|
def update(self, *args):
|
||||||
|
"""
|
||||||
|
This method is called every frame. If there is something in buffer, then it is written to console.
|
||||||
|
|
||||||
|
:param args:
|
||||||
|
"""
|
||||||
|
while len(UiConsole.buffer) > 0:
|
||||||
|
self.__writeToConsole__(UiConsole.buffer.pop(0))
|
||||||
|
|
||||||
|
def __writeToConsole__(self, inp: str):
|
||||||
|
"""
|
||||||
|
Writes given string to console and scrolls (console) down to display it.
|
||||||
|
Warning: It is advised to use printToConsole() method.
|
||||||
|
|
||||||
|
:param inp: String to be written to console.
|
||||||
|
"""
|
||||||
|
self.addLinesToConsoleAndScrollToDisplayThem([inp])
|
||||||
|
|
||||||
|
def scrollUp(self):
|
||||||
|
"""
|
||||||
|
Scrolls one line up.
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.__writeConsoleLines__(self.topWrittenLineInd - 1)
|
||||||
|
|
||||||
|
def scrollDown(self):
|
||||||
|
"""
|
||||||
|
Scrolls one line down.
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.__writeConsoleLines__(self.topWrittenLineInd + 1)
|
||||||
|
|
||||||
|
def __writeConsoleLines__(self, startingLineInd: int = 0):
|
||||||
|
"""
|
||||||
|
Displays lines stored in console's list of lines, starting from line with given index.
|
||||||
|
|
||||||
|
:param startingLineInd: Line index, which will be written on top of the console.
|
||||||
|
"""
|
||||||
self.image.fill(self.bgColor)
|
self.image.fill(self.bgColor)
|
||||||
if startingLineInd < 0:
|
if startingLineInd < 0:
|
||||||
startingLineInd = 0
|
startingLineInd = 0
|
||||||
@ -44,7 +120,15 @@ class UiConsole(UiElement):
|
|||||||
self.image.blit(self.linesImages[i], (0, writtenLines * self.lineHeight))
|
self.image.blit(self.linesImages[i], (0, writtenLines * self.lineHeight))
|
||||||
writtenLines += 1
|
writtenLines += 1
|
||||||
|
|
||||||
def addLinesToConsole(self, linesToAdd):
|
def addLinesToConsole(self, linesToAdd: List[str]):
|
||||||
|
"""
|
||||||
|
Adds lines to console's list of lines. If one line is too long to display, then it is being cut to pieces,
|
||||||
|
so that it is appropriate size.
|
||||||
|
|
||||||
|
Warning: this method doesn't display given lines, just adds to list of lines.
|
||||||
|
|
||||||
|
:param linesToAdd:
|
||||||
|
"""
|
||||||
for line in linesToAdd:
|
for line in linesToAdd:
|
||||||
self.consoleLines.append(line)
|
self.consoleLines.append(line)
|
||||||
self.linesCount += 1
|
self.linesCount += 1
|
||||||
@ -72,9 +156,14 @@ class UiConsole(UiElement):
|
|||||||
self.linesImages.append(row)
|
self.linesImages.append(row)
|
||||||
self.linesImagesCount += 1
|
self.linesImagesCount += 1
|
||||||
|
|
||||||
def addLinesToConsoleAndScrollToDisplayThem(self, linesToAdd):
|
def addLinesToConsoleAndScrollToDisplayThem(self, linesToAdd: List[str]):
|
||||||
|
"""
|
||||||
|
Adds given lines to console's list of lines, writes them and scrolls console down to display them.
|
||||||
|
|
||||||
|
:param linesToAdd: Lines to add to console's list of lines and to display.
|
||||||
|
"""
|
||||||
self.addLinesToConsole(linesToAdd)
|
self.addLinesToConsole(linesToAdd)
|
||||||
ind = 0
|
ind = 0
|
||||||
if self.linesImagesCount > self.maxLines:
|
if self.linesImagesCount > self.maxLines:
|
||||||
ind = self.linesImagesCount - self.maxLines
|
ind = self.linesImagesCount - self.maxLines
|
||||||
self.writeConsoleLines(ind)
|
self.__writeConsoleLines__(ind)
|
||||||
|
@ -2,6 +2,12 @@ import pygame
|
|||||||
|
|
||||||
|
|
||||||
class UiElement(pygame.sprite.Sprite):
|
class UiElement(pygame.sprite.Sprite):
|
||||||
def __init__(self, rect):
|
rect: pygame.Rect
|
||||||
|
|
||||||
|
def __init__(self, rect: pygame.Rect):
|
||||||
|
"""
|
||||||
|
Creates UiElement object.
|
||||||
|
:param rect: UiElement will be drawn on this rectangle.
|
||||||
|
"""
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.rect = rect
|
self.rect = rect
|
||||||
|
@ -3,7 +3,14 @@ import pygame
|
|||||||
|
|
||||||
|
|
||||||
class UiImage(UiElement):
|
class UiImage(UiElement):
|
||||||
|
image: pygame.Surface
|
||||||
|
|
||||||
def __init__(self, rect: pygame.Rect, image: pygame.Surface):
|
def __init__(self, rect: pygame.Rect, image: pygame.Surface):
|
||||||
|
"""
|
||||||
|
Creates UiImage object.
|
||||||
|
:param rect: Rectangle on which image will be displayed
|
||||||
|
:param image: Image to display
|
||||||
|
"""
|
||||||
super().__init__(rect)
|
super().__init__(rect)
|
||||||
self.image = pygame.transform.scale(image, (rect.width, rect.height))
|
self.image = pygame.transform.scale(image, (rect.width, rect.height))
|
||||||
|
|
||||||
|
@ -1,14 +1,32 @@
|
|||||||
from typing import Tuple
|
from typing import Tuple, Union
|
||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
|
from pygame.font import FontType
|
||||||
|
|
||||||
from src.ui.UiElement import UiElement
|
from src.ui.UiElement import UiElement
|
||||||
|
|
||||||
|
|
||||||
class UiText(UiElement):
|
class UiText(UiElement):
|
||||||
|
image: pygame.Surface
|
||||||
|
font: pygame.font.Font
|
||||||
|
text: str
|
||||||
|
antialias: bool
|
||||||
|
textColor: Tuple[int, int, int]
|
||||||
|
backgroundColor: Tuple[int, int, int]
|
||||||
|
|
||||||
def __init__(self, rect: pygame.Rect, text: str, font: pygame.font.Font = None,
|
def __init__(self, rect: pygame.Rect, text: str, font: pygame.font.Font = None,
|
||||||
textColor=(0, 0, 0), antialias: bool = False,
|
textColor: Tuple[int, int, int] = (0, 0, 0), antialias: bool = False,
|
||||||
backgroundColor=None):
|
backgroundColor: Union[Tuple[int, int, int], None] = None):
|
||||||
|
"""
|
||||||
|
Creates UiText object.
|
||||||
|
|
||||||
|
:param rect: Rectangle on which text view will be drawn.
|
||||||
|
:param text:
|
||||||
|
:param font: If no font is given then default pygame font will be used.
|
||||||
|
:param textColor:
|
||||||
|
:param antialias:
|
||||||
|
:param backgroundColor: Can be None.
|
||||||
|
"""
|
||||||
super().__init__(rect)
|
super().__init__(rect)
|
||||||
|
|
||||||
self.backgroundColor = backgroundColor
|
self.backgroundColor = backgroundColor
|
||||||
@ -25,7 +43,12 @@ class UiText(UiElement):
|
|||||||
wordImage = self.font.render(text, antialias, textColor)
|
wordImage = self.font.render(text, antialias, textColor)
|
||||||
self.image.blit(wordImage, (0, 0))
|
self.image.blit(wordImage, (0, 0))
|
||||||
|
|
||||||
def changeText(self, newText):
|
def changeText(self, newText: str):
|
||||||
|
"""
|
||||||
|
Changes text view's text.
|
||||||
|
|
||||||
|
:param newText:
|
||||||
|
"""
|
||||||
self.text = newText
|
self.text = newText
|
||||||
|
|
||||||
if self.backgroundColor is not None:
|
if self.backgroundColor is not None:
|
||||||
|
Loading…
Reference in New Issue
Block a user