From f1155a43e73bb3e0ca4b6dc79046fa77513643b4 Mon Sep 17 00:00:00 2001 From: Giovani Date: Tue, 13 Jul 2021 11:58:52 -0400 Subject: [PATCH] feat: add multiplayer piece generation --- config.yaml | 9 +++-- tetri5/entity.py | 22 +++++----- tetri5/scene.py | 103 +++++++++++++++++++++++++++++++++-------------- 3 files changed, 91 insertions(+), 43 deletions(-) diff --git a/config.yaml b/config.yaml index 6b210e3..c612f8c 100644 --- a/config.yaml +++ b/config.yaml @@ -44,10 +44,11 @@ position: score-value-player-2: [540, 40] lines-label-player-1: [100, 540] lines-label-player-2: [500, 540] - next-label-player-1: [340, 180] - next-piece-player-1: [360, 220] - next-label-player-2: [340, 360] - next-piece-player-2: [360, 400] + next-label-player-1: [340, 120] + next-piece-player-1: [360, 160] + next-label-player-2: [340, 420] + next-piece-player-2: [360, 460] + spawn-piece-player-1: [-260, -60] engine: fps: 60 diff --git a/tetri5/entity.py b/tetri5/entity.py index 647b873..ebc5bf1 100644 --- a/tetri5/entity.py +++ b/tetri5/entity.py @@ -368,22 +368,24 @@ class _SquareDesign: """ class PieceGenerator: - _bucket = [] + _bucket_one = [] + _bucket_two = [] @classmethod - def get_piece(cls, position: Tuple) -> Piece: - if len(cls._bucket) == 0: - cls._generate_bucket() + def get_piece(cls, position: Tuple, player_two: bool = False) -> Piece: + bucket = cls._bucket_one if not player_two else cls._bucket_two + if len(bucket) == 0: + cls._generate_bucket(bucket) base_color, inner_border_color, outer_border_color = cls._get_piece_color() - return Piece(cls._get_piece_shape(cls._bucket.pop()), position, base_color, inner_border_color, outer_border_color) + return Piece(cls._get_piece_shape(bucket.pop()), position, base_color, inner_border_color, outer_border_color) @classmethod - def _generate_bucket(cls) -> None: + def _generate_bucket(cls, bucket: List) -> None: piece_types = list(range(7)) - while len(cls._bucket) != 7: - random_number = random.randint(0, 6 - len(cls._bucket)) - cls._bucket.append(piece_types.pop(random_number)) + while len(bucket) != 7: + random_number = random.randint(0, 6 - len(bucket)) + bucket.append(piece_types.pop(random_number)) def _get_piece_shape(piece_number: int) -> Tuple: if piece_number == 0: @@ -405,7 +407,9 @@ class PieceGenerator: def _get_piece_color() -> Tuple: random_number = random.randint(1, 3) + base_color = ConfigurationManager.get("color", "piece-" + str(random_number)) inner_border_color = None if random_number != 3 else ConfigurationManager.get("color", "piece-inner-border-1") outer_border_color = ConfigurationManager.get("color", "piece-outer-border-1") + return (base_color, inner_border_color, outer_border_color) \ No newline at end of file diff --git a/tetri5/scene.py b/tetri5/scene.py index e7b2e09..47202b8 100644 --- a/tetri5/scene.py +++ b/tetri5/scene.py @@ -110,15 +110,15 @@ class SinglePlayerScene(Scene): def draw(self, surface: pygame.Surface) -> None: surface.fill(self._background_color) - if self._next_piece: - self._next_piece.draw(surface) - if self._well: - self._well.draw(surface) if self._stack: self._stack.draw(surface) if self._current_piece: self._current_piece.draw(surface, self._well, self._stack) - + if self._next_piece: + self._next_piece.draw(surface) + if self._well: + self._well.draw(surface) + score = str(self._score).zfill(6) lines = str(self._stack.total_lines).zfill(4) level = str(self._get_level()).zfill(2) @@ -170,6 +170,7 @@ class MultiPlayerScene(Scene): def __init__(self, change_scene: FunctionType) -> None: self._tile_size = ConfigurationManager.get("engine", "tile-size") self._background_color = pygame.Color(ConfigurationManager.get("color", "window-bg")) + self._lines_per_level = ConfigurationManager.get("engine", "lines-per-level") # wells init self._well_player_one = Well(ConfigurationManager.get("position", "well-player-1"),\ @@ -184,18 +185,29 @@ class MultiPlayerScene(Scene): self._stack_player_two = Stack() # score positions - self.score_label_player_one_pos = ConfigurationManager.get("position", "score-label-player-1") - self.score_label_player_two_pos = ConfigurationManager.get("position", "score-label-player-2") - self.score_value_player_one_pos = ConfigurationManager.get("position", "score-value-player-1") - self.score_value_player_two_pos = ConfigurationManager.get("position", "score-value-player-2") + self._score_label_player_one_pos = ConfigurationManager.get("position", "score-label-player-1") + self._score_label_player_two_pos = ConfigurationManager.get("position", "score-label-player-2") + self._score_value_player_one_pos = ConfigurationManager.get("position", "score-value-player-1") + self._score_value_player_two_pos = ConfigurationManager.get("position", "score-value-player-2") # lines positions - self.lines_label_player_one_pos = ConfigurationManager.get("position", "lines-label-player-1") - self.lines_label_player_two_pos = ConfigurationManager.get("position", "lines-label-player-2") + self._lines_label_player_one_pos = ConfigurationManager.get("position", "lines-label-player-1") + self._lines_label_player_two_pos = ConfigurationManager.get("position", "lines-label-player-2") # next positions - self.next_label_player_one_pos = ConfigurationManager.get("position", "next-label-player-1") - self.next_label_player_two_pos = ConfigurationManager.get("position", "next-label-player-2") + self._next_label_player_one_pos = ConfigurationManager.get("position", "next-label-player-1") + self._next_label_player_two_pos = ConfigurationManager.get("position", "next-label-player-2") + + # piece positions + self._next_piece_player_one_pos = ConfigurationManager.get("position", "next-piece-player-1") + self._next_piece_player_two_pos = ConfigurationManager.get("position", "next-piece-player-2") + self._spawn_piece_shift_player_one = ConfigurationManager.get("position", "spawn-piece-player-1") + + # entities + self._next_piece_player_one = PieceGenerator.get_piece(self._next_piece_player_one_pos) + self._next_piece_player_two = PieceGenerator.get_piece(self._next_piece_player_two_pos) + self._current_piece_player_one = None + self._current_piece_player_two = None self._change_scence = change_scene MultiplayerService.init() @@ -203,31 +215,62 @@ class MultiPlayerScene(Scene): def draw(self, surface: pygame.Surface) -> None: surface.fill(self._background_color) - # wells - if self._well_player_one: - self._well_player_one.draw(surface) - if self._well_player_two: - self._well_player_two.draw(surface) - # stacks - if self._stack_player_one: + if self._stack_player_one is not None: self._stack_player_one.draw(surface) - if self._stack_player_two: + if self._stack_player_two is not None: self._stack_player_two.draw(surface) + # pieces + if self._current_piece_player_one is not None: + self._current_piece_player_one.draw(surface) + if self._current_piece_player_two is not None: + self._current_piece_player_two.draw(surface) + if self._next_piece_player_one is not None: + self._next_piece_player_one.draw(surface) + if self._next_piece_player_two is not None: + self._next_piece_player_two.draw(surface) + + # wells + if self._well_player_one is not None: + self._well_player_one.draw(surface) + if self._well_player_two is not None: + self._well_player_two.draw(surface) + # scores - TextGenerator.draw("Score", self.score_label_player_one_pos, surface) - TextGenerator.draw("000000", self.score_value_player_one_pos, surface) - TextGenerator.draw("Score", self.score_label_player_two_pos, surface) - TextGenerator.draw("000000", self.score_value_player_two_pos, surface) + TextGenerator.draw("Score", self._score_label_player_one_pos, surface) + TextGenerator.draw("000000", self._score_value_player_one_pos, surface) + TextGenerator.draw("Score", self._score_label_player_two_pos, surface) + TextGenerator.draw("000000", self._score_value_player_two_pos, surface) # lines - TextGenerator.draw("Lines 0000", self.lines_label_player_one_pos, surface) - TextGenerator.draw("Lines 0000", self.lines_label_player_two_pos, surface) + TextGenerator.draw("Lines 0000", self._lines_label_player_one_pos, surface) + TextGenerator.draw("Lines 0000", self._lines_label_player_two_pos, surface) # next - TextGenerator.draw("P1 NXT", self.next_label_player_one_pos, surface) - TextGenerator.draw("P2 NXT", self.next_label_player_two_pos, surface) + TextGenerator.draw("P1 NXT", self._next_label_player_one_pos, surface) + TextGenerator.draw("P2 NXT", self._next_label_player_two_pos, surface) def update(self, elapsed_time: int) -> None: - pass + if self._current_piece_player_one is not None: + self._current_piece_player_one.update(elapsed_time,\ + self._well_player_one,\ + self._stack_player_one,\ + self._get_level(),\ + self._clear_current_piece) + else: + self._current_piece_player_one = self._next_piece_player_one + self._current_piece_player_one.move(self._spawn_piece_shift_player_one) + self._next_piece_player_one = PieceGenerator.get_piece(self._next_piece_player_one_pos) + + # TODO create game over scene + if self._stack_player_one and self._current_piece_player_one.collide(self._stack_player_one): + pygame.quit() + MultiplayerService.quit() + sys.exit() + + def _get_level(self) -> int: + return 0 if self._stack_player_one is None else self._stack_player_one.total_lines // self._lines_per_level + + def _clear_current_piece(self) -> None: + self._current_piece_player_one = None