diff --git a/src/py2048/objects/__init__.py b/src/py2048/objects/__init__.py index 0002bf8..8eac17f 100644 --- a/src/py2048/objects/__init__.py +++ b/src/py2048/objects/__init__.py @@ -1,6 +1,7 @@ from .board import Board from .button import Button from .label import Label +from .score_label import ScoreLabel from .tile import Tile -__all__ = ["Board", "Button", "Label", "Tile"] +__all__ = ["Board", "Button", "Label", "Tile", "ScoreLabel"] diff --git a/src/py2048/objects/button.py b/src/py2048/objects/button.py index ae1385d..208b527 100644 --- a/src/py2048/objects/button.py +++ b/src/py2048/objects/button.py @@ -7,7 +7,7 @@ from attrs import define, field from py2048 import Config from py2048.utils import Direction, Position -from .abc import ClickableUIElement, UIElement +from .abc import ClickableUIElement class Button(ClickableUIElement, pygame.sprite.Sprite): @@ -30,7 +30,6 @@ class Button(ClickableUIElement, pygame.sprite.Sprite): """Update the button.""" self._draw_background(self.image) self._draw_text() - self.image.blit(self.image, (0, 0)) def on_click(self, mouse_pos: Position) -> None: """Handle the click event.""" @@ -61,11 +60,9 @@ class Button(ClickableUIElement, pygame.sprite.Sprite): def _draw_text(self) -> None: """Draw the text of the element.""" - self.rendered_text = self.font.render(self.text, True, self.font_color) - self.image.blit( - self.rendered_text, - self.rendered_text.get_rect(center=self.image.get_rect().center), - ) + text = self.font.render(self.text, True, self.font_color) + rect = text.get_rect(center=self.image.get_rect().center) + self.image.blit(text, rect) def _create_surface(self) -> pygame.Surface: """Create a surface for the element.""" diff --git a/src/py2048/objects/label.py b/src/py2048/objects/label.py index eaaf6e7..9e5d009 100644 --- a/src/py2048/objects/label.py +++ b/src/py2048/objects/label.py @@ -41,11 +41,9 @@ class Label(UIElement, pygame.sprite.Sprite): def _draw_text(self) -> None: """Draw the text of the element.""" - self.rendered_text = self.font.render(self.text, True, self.font_color) - self.image.blit( - self.rendered_text, - self.rendered_text.get_rect(center=self.image.get_rect().center), - ) + text = self.font.render(self.text, True, self.font_color) + rect = text.get_rect(center=self.image.get_rect().center) + self.image.blit(text, rect) def _create_surface(self) -> pygame.Surface: """Create a surface for the element.""" diff --git a/src/py2048/objects/score_label.py b/src/py2048/objects/score_label.py new file mode 100644 index 0000000..01a9d85 --- /dev/null +++ b/src/py2048/objects/score_label.py @@ -0,0 +1,65 @@ +from typing import Optional + +import pygame +from loguru import logger + +from py2048 import Config +from py2048.utils import Position, Size + +from .abc import UIElement + + +class ScoreLabel(UIElement, pygame.sprite.Sprite): + def __init__(self, value: int, *args, **kwargs) -> None: + pygame.sprite.Sprite.__init__(self) + super().__init__(*args, **kwargs) + self.value = value + self.image = self._create_surface() + self.rect = self.image.get_rect() + self.rect.topleft = self.position + self.update() + + def draw(self, surface: pygame.Surface) -> None: + """Draw the element on the given surface.""" + self._draw_background(surface) + self._draw_text() + + def update(self) -> None: + """Update the sprite.""" + self._draw_background(self.image) + self._draw_text() + + def update_score(self, score: int) -> None: + """Update the score value.""" + self.value = score + self.update() + + def _draw_background(self, surface: pygame.Surface) -> None: + """Draw a background for the given surface.""" + if self.size: + pygame.draw.rect( + surface, + self.bg_color, + (0, 0, *self.size), + border_radius=self.border_radius, + ) + + def _draw_text(self) -> None: + """Draw the text of the element.""" + centerx, centery = self.image.get_rect().center + + # Render text + label_text = self.font.render(self.text, True, self.font_color) + label_rect = label_text.get_rect(center=(centerx, centery - 10)) + self.image.blit(label_text, label_rect) + + # Render value + score_text = self.font.render(f"{self.value}", True, self.font_color) + score_rect = score_text.get_rect(center=(centerx, centery + 10)) + self.image.blit(score_text, score_rect) + + def _create_surface(self) -> pygame.Surface: + """Create a surface for the element.""" + surface = pygame.Surface(self.size, pygame.SRCALPHA) + self._draw_background(surface) + return surface diff --git a/src/py2048/objects/tile.py b/src/py2048/objects/tile.py index 90a3f67..2ef9664 100644 --- a/src/py2048/objects/tile.py +++ b/src/py2048/objects/tile.py @@ -78,11 +78,9 @@ class Tile(MovableUIElement, pygame.sprite.Sprite): def _draw_text(self) -> None: """Draw the text of the sprite.""" - self.rendered_text = self.font.render(self.text, True, self.font_color) - self.image.blit( - self.rendered_text, - self.rendered_text.get_rect(center=self.image.get_rect().center), - ) + text = self.font.render(self.text, True, self.font_color) + rect = (text.get_rect(center=self.image.get_rect().center),) + self.image.blit(text, rect) def _create_surface(self) -> pygame.Surface: """Create a surface for the sprite.""" diff --git a/src/py2048/screens/game.py b/src/py2048/screens/game.py index b2e8b06..21fde46 100644 --- a/src/py2048/screens/game.py +++ b/src/py2048/screens/game.py @@ -16,7 +16,7 @@ class Game: def draw(self, surface: pygame.Surface) -> None: surface.fill(Config.COLORSCHEME.BG) self.board.draw(surface) - self.header.draw(surface, 2048) + self.header.draw(surface) pygame.display.flip() def handle_events(self, event: pygame.Event) -> None: diff --git a/src/py2048/screens/header.py b/src/py2048/screens/header.py index e00e528..432148a 100644 --- a/src/py2048/screens/header.py +++ b/src/py2048/screens/header.py @@ -1,7 +1,7 @@ import pygame from py2048 import Config -from py2048.objects import Label +from py2048.objects import ScoreLabel from py2048.utils import Position, Size @@ -11,29 +11,42 @@ class Header: self.labels = self._create_labels() def _create_labels(self) -> pygame.sprite.Group: - score = Label( - text=f"SCORE\n{0}", - size=Size(50, 50), - position=Position(0, 0), + size = Size(60, 40) + + score = ScoreLabel( + value=0, + text="Score", + size=size, + position=Position( + Config.SCREEN.size.width - Config.TILE.size // 2 - size.width * 2 - 10, + 10, + ), bg_color=Config.COLORSCHEME.BOARD_BG, font_color=Config.COLORSCHEME.LIGHT_TEXT, font_size=16, + border_radius=2, ) - highscore = Label( - text=f"HIGHSCORE\n{2048}", - size=Size(50, 50), - position=Position(200, 0), + highscore = ScoreLabel( + value=2048, + text="Best", + size=size, + position=Position( + Config.SCREEN.size.width - Config.TILE.size // 2 - size.width, 10 + ), bg_color=Config.COLORSCHEME.BOARD_BG, font_color=Config.COLORSCHEME.LIGHT_TEXT, font_size=16, + border_radius=2, ) + return pygame.sprite.Group(score, highscore) - def draw(self, screen: pygame.Surface, score: int) -> None: + def draw(self, surface: pygame.Surface) -> None: """Draw the header.""" - self.labels.draw(screen) + self.labels.draw(surface) def update(self, score: int) -> None: """Update the header.""" - # self.labels. = f"SCORE\n{score}" - self.labels.update() + for label in self.labels: + if label.text == "SCORE": + label.update_score(score)