feat(game): add scoring mechanic

This commit is contained in:
Kristofers Solo 2024-01-04 06:29:18 +02:00
parent ee179036e2
commit 384a4d8d74
4 changed files with 42 additions and 6 deletions

View File

@ -11,7 +11,11 @@ from .timer import Timer, Timers
class Game:
def __init__(self, get_next_figure: Callable[[], Figure]) -> None:
def __init__(
self,
get_next_figure: Callable[[], Figure],
update_score: Callable[[int, int, int], None],
) -> None:
self.surface = pygame.Surface(CONFIG.game.size)
self.dispaly_surface = pygame.display.get_surface()
self.rect = self.surface.get_rect(topleft=CONFIG.game.pos)
@ -19,6 +23,7 @@ class Game:
self.sprites: pygame.sprite.Group[Block] = pygame.sprite.Group()
self.get_next_shape = get_next_figure
self.update_score = update_score
self._create_grid_surface()
@ -38,9 +43,12 @@ class Game:
Timer(CONFIG.game.movment_delay),
Timer(CONFIG.game.rotation_delay),
)
self.timers.vertical.activate()
self.level = 1
self.score = 0
self.lines = 0
def run(self) -> None:
self.dispaly_surface.blit(self.surface, CONFIG.game.pos)
self.draw()
@ -162,6 +170,7 @@ class Game:
def _delete_rows(self, delete_rows: list[int]) -> None:
if not delete_rows:
return
self._calculate_score(len(delete_rows))
for row in delete_rows:
for block in self.field[row]:
@ -184,3 +193,16 @@ class Game:
def _generate_empty_field(self) -> np.ndarray:
return np.full((CONFIG.game.rows, CONFIG.game.columns), None, dtype=Field)
def _calculate_score(self, rows_deleted: int) -> None:
self.lines += rows_deleted
self.score += CONFIG.game.score.get(rows_deleted, 0) * self.level
# every 10 lines increase level
if self.lines // 10 + 1 > self.level:
self.level += 1
self.initial_block_speed *= 0.75
self.increased_block_speed *= 0.75
self.timers.vertical.duration = self.initial_block_speed
self.update_score(self.lines, self.score, self.level)

View File

@ -20,7 +20,7 @@ class Main:
self.next_figures = self._generate_next_figures()
self.game = Game(self._get_next_figure)
self.game = Game(self._get_next_figure, self._update_score)
self.score = Score()
self.preview = Preview()
@ -39,6 +39,9 @@ class Main:
pygame.display.update()
self.clock.tick(CONFIG.fps)
def _update_score(self, lines: int, score: int, level: int) -> None:
self.score.update(lines, score, level)
def handle_events(self) -> None:
for event in pygame.event.get():
if event.type == pygame.QUIT:

View File

@ -11,7 +11,8 @@ class Score:
)
self.font = pygame.font.Font(CONFIG.font.family, CONFIG.font.size)
self.text = ["Score", "Level", "Lines"]
self.update(1, 0, 0)
self.increment_height = self.surface.get_height() / 3
@ -19,6 +20,13 @@ class Score:
self.dispaly_surface.blit(self.surface, self.rect)
self.draw()
def update(self, lines: int, score: int, level: int) -> None:
self.text = (
("Score", score),
("Level", level),
("Lines", lines),
)
def draw(self) -> None:
self.surface.fill(CONFIG.colors.bg_sidebar)
self._draw_text()
@ -30,8 +38,10 @@ class Score:
y = self.increment_height / 2 + idx * self.increment_height
self._display_text(text, (x, y))
def _display_text(self, text: str, pos: tuple[int, int]) -> None:
text_surface = self.font.render(text, True, CONFIG.colors.fg_sidebar)
def _display_text(self, text: tuple[str, int], pos: tuple[int, int]) -> None:
text_surface = self.font.render(
f"{text[0]}: {text[1]}", True, CONFIG.colors.fg_sidebar
)
text_rect = text_surface.get_rect(center=pos)
self.surface.blit(text_surface, text_rect)

View File

@ -24,6 +24,7 @@ class Game:
initial_speed: int = 400
movment_delay: int = 200
rotation_delay: int = 200
score: dict[int, int] = {1: 40, 2: 100, 3: 300, 4: 1200}
@define