feat(game): dispaly current score

This commit is contained in:
Kristofers Solo 2024-01-03 01:53:43 +02:00
parent fce7ec17e1
commit 692d5dd859
5 changed files with 25 additions and 29 deletions

View File

@ -1,4 +1,5 @@
from abc import abstractmethod from abc import abstractmethod
from typing import Any
import pygame import pygame
@ -12,7 +13,7 @@ class MovableUIElement(UIElement):
UIElement.__init__(self, *args, **kwargs) UIElement.__init__(self, *args, **kwargs)
@abstractmethod @abstractmethod
def move(self, direction: Direction) -> None: def move(self, direction: Direction) -> Any:
"""Move the element in the given direction.""" """Move the element in the given direction."""
@property @property

View File

@ -15,16 +15,15 @@ class Board(pygame.sprite.Group):
self.rect = pygame.Rect(0, 0, *Config.BOARD.size) self.rect = pygame.Rect(0, 0, *Config.BOARD.size)
self.score: int = 0 self.score: int = 0
self.rect.x, self.rect.y = Config.BOARD.pos self.rect.x, self.rect.y = Config.BOARD.pos
self.initiate_game() self._initiate_game()
def initiate_game(self) -> None: def _initiate_game(self) -> None:
"""Initiate the game.""" """Initiate the game."""
self.generate_initial_tiles() self.generate_initial_tiles()
def draw(self, surface: pygame.Surface) -> None: def draw(self, surface: pygame.Surface) -> None:
"""Draw the board.""" """Draw the board."""
self._draw_background(surface) self._draw_background(surface)
super().draw(surface) super().draw(surface)
def _draw_background(self, surface: pygame.Surface) -> None: def _draw_background(self, surface: pygame.Surface) -> None:
@ -45,7 +44,6 @@ class Board(pygame.sprite.Group):
def move(self, direction: Direction) -> None: def move(self, direction: Direction) -> None:
"""Move the tiles in the specified direction.""" """Move the tiles in the specified direction."""
score = 0
tiles = self.sprites() tiles = self.sprites()
tile: Tile tile: Tile
@ -60,8 +58,7 @@ class Board(pygame.sprite.Group):
tiles.sort(key=lambda tile: tile.rect.x, reverse=True) tiles.sort(key=lambda tile: tile.rect.x, reverse=True)
for tile in tiles: for tile in tiles:
tile.move(direction) self.score += tile.move(direction)
self.score += tile.value
if not self._is_full(): if not self._is_full():
self.generate_random_tile() self.generate_random_tile()
@ -116,4 +113,4 @@ class Board(pygame.sprite.Group):
def reset(self) -> None: def reset(self) -> None:
"""Reset the board.""" """Reset the board."""
self.empty() self.empty()
self.initiate_game() self._initiate_game()

View File

@ -33,7 +33,6 @@ class Tile(MovableUIElement, pygame.sprite.Sprite):
border_radius=Config.TILE.border.radius, border_radius=Config.TILE.border.radius,
border_width=Config.TILE.border.width, border_width=Config.TILE.border.width,
) )
self.score: int = 0
self.group = group self.group = group
self.image = self._create_surface() self.image = self._create_surface()
@ -88,33 +87,29 @@ class Tile(MovableUIElement, pygame.sprite.Sprite):
self._draw_background(surface) self._draw_background(surface)
return surface return surface
def move(self, direction: Direction) -> None: def move(self, direction: Direction) -> int:
""" """
Move the tile by `dx` and `dy`. Move the tile by `dx` and `dy`.
If the tile collides with another tile, it will merge with it if possible. If the tile collides with another tile, it will merge with it if possible.
Before moving, reset the score of the tile.
""" """
score = 0
while True: while True:
new_x, new_y = self._calc_new_pos(direction) new_x, new_y = self._calc_new_pos(direction)
if self._is_out_if_bounds(new_x, new_y): if self._is_out_if_bounds(new_x, new_y):
return return score
if self._has_collision(new_x, new_y): if self._has_collision(new_x, new_y):
collided_tile = self._get_collided_tile(new_x, new_y) collided_tile = self._get_collided_tile(new_x, new_y)
if collided_tile and self._can_merge(collided_tile): if collided_tile and self._can_merge(collided_tile):
self._merge(collided_tile) score += self._merge(collided_tile)
else: else:
return return score
self.group.remove(self) self.group.remove(self)
self.rect.topleft = new_x, new_y self.rect.topleft = new_x, new_y
self.group.add(self) self.group.add(self)
def get_score(self) -> int:
"""Return the score of the tile."""
return self.score
def _calc_new_pos(self, direction: Direction) -> tuple[int, int]: def _calc_new_pos(self, direction: Direction) -> tuple[int, int]:
"""Calculate the new position of the tile.""" """Calculate the new position of the tile."""
dx, dy = direction * Config.TILE.size dx, dy = direction * Config.TILE.size
@ -148,13 +143,14 @@ class Tile(MovableUIElement, pygame.sprite.Sprite):
"""Check if the tile can merge with another tile.""" """Check if the tile can merge with another tile."""
return self.value == other.value return self.value == other.value
def _merge(self, other: "Tile") -> None: def _merge(self, other: "Tile") -> int:
"""Merge the tile with another tile.""" """Merge the tile with another tile."""
self.group.remove(other) self.group.remove(other)
self.group.remove(self) self.group.remove(self)
self.value += other.value self.value += other.value
self.update() self.update()
self.group.add(self) self.group.add(self)
return self.value
def can_move(self) -> bool: def can_move(self) -> bool:
"""Check if the tile can move""" """Check if the tile can move"""

View File

@ -30,14 +30,18 @@ class Game:
elif event.key in (pygame.K_DOWN, pygame.K_s, pygame.K_j): elif event.key in (pygame.K_DOWN, pygame.K_s, pygame.K_j):
self.move_down() self.move_down()
def move(self, direction: Direction) -> None:
self.board.move(direction)
self.header.update(self.board.score)
def move_up(self) -> None: def move_up(self) -> None:
self.board.move(Direction.UP) self.move(Direction.UP)
def move_down(self) -> None: def move_down(self) -> None:
self.board.move(Direction.DOWN) self.move(Direction.DOWN)
def move_left(self) -> None: def move_left(self) -> None:
self.board.move(Direction.LEFT) self.move(Direction.LEFT)
def move_right(self) -> None: def move_right(self) -> None:
self.board.move(Direction.RIGHT) self.move(Direction.RIGHT)

View File

@ -13,7 +13,7 @@ class Header:
def _create_labels(self) -> pygame.sprite.Group: def _create_labels(self) -> pygame.sprite.Group:
size = Size(60, 40) size = Size(60, 40)
score = ScoreLabel( self.score = ScoreLabel(
value=0, value=0,
text="Score", text="Score",
size=size, size=size,
@ -39,14 +39,12 @@ class Header:
border_radius=2, border_radius=2,
) )
return pygame.sprite.Group(score, highscore) return pygame.sprite.Group(self.score, highscore)
def draw(self, surface: pygame.Surface) -> None: def draw(self, surface: pygame.Surface) -> None:
"""Draw the header.""" """Draw the header."""
self.labels.draw(surface) self.labels.draw(surface)
def update(self, score: int) -> None: def update(self, score: int) -> None:
"""Update the header.""" """Update the score."""
for label in self.labels: self.score.update_score(score)
if label.text == "SCORE":
label.update_score(score)