def get_dropping_squares(self) -> Dict[Piece, Point]: dropping_pieces: Dict[Piece, Point] = {} empty = self._get_first_unoccupied_square() if empty is None: return {} index_empty = self.children.index(empty) occupied = self._get_first_occupied_square(index_empty) if occupied is None: self.fill_column(index_empty + 1) new_items: int = index_empty + 1 else: index_occupied = self.children.index(occupied) point = Point(empty.position.x, empty.position.y) delta_point = Point(0, Piece.PIECE_SIZE.height) idx = index_occupied while idx >= 0: dropping_pieces[self.children[idx]] = point point = point - delta_point idx -= 1 self.fill_column(index_empty + 1, index_occupied + 1) new_items = index_empty - index_occupied + 1 for idx in range(0, new_items): piece = self.children[idx] dropping_pieces[piece] = Point(0, idx * Piece.PIECE_SIZE.height) return dropping_pieces
def __init__(self, position: Tuple[int, int], size: Tuple[int, int]): self.__position: Point = Point(position[0], position[1]) self.__size: Size = Size(size[0], size[1]) self.__color: pygame.Color = None self.__children: List[GameObject] = [] self.__only_border: bool = False self.__sprite: Sprite = None
def draw_window(self): if self.color is not None: self.__screen.fill(self.color) for obj in self.__objects: obj.draw(self.__screen, Point(0, 0)) pygame.display.flip()
def handle(self, event: pygame.event.Event): board: MatchThreeBoard = None offset: int = -1 animations: List[MovementAnimation] = [] if event.button != 1: return board, offset = self.args position = Point(event.pos[0], event.pos[1]) - offset prev_square = board.get_children_in_position(self.__previous) current_square = board.get_children_in_position(position) if current_square is None: return if not board.are_neighbours(prev_square, current_square): board.reset_tiles() current_square.selected = True self.__previous = position elif prev_square is not None and current_square is not None and prev_square == current_square: current_square.selected = not current_square.selected self.__previous = position elif prev_square is not None and prev_square.selected: if self.draw_function is not None: animations += animate_swap(prev_square, current_square, self.draw_function, board) for animation in animations: animation.join() animations.clear() board.swap_children(prev_square, current_square) board.reset_tiles() matches = [prev_square, current_square] while matches: # if True: self.handle_matches(matches, board) dropping_pieces = [] while are_there_dropping_pieces(board, dropping_pieces): self.drop_squares_on_board(dropping_pieces) dropping_pieces.clear() matches = get_all_matches_on_board(board) # time.sleep(0.05) self.__previous = Point(0, 0)
def animate_swap(piece1: Piece, piece2: Piece, draw_function: Callable[[], None], board: MatchThreeBoard) -> List[MovementAnimation]: animations: List[MovementAnimation] = [] row1, column1 = board.get_position_of_piece(piece1) row2, column2 = board.get_position_of_piece(piece2) final_position1 = Point(piece2.position.x, piece2.position.y) final_position2 = Point(piece1.position.x, piece1.position.y) if column1 < column2: final_position1.x += piece1.size.width final_position2.x -= piece1.size.width step_point = Point(- Piece.PIECE_SIZE.width / 10, 0) elif column1 > column2: final_position1.x -= piece1.size.width final_position2.x += piece1.size.width step_point = Point(Piece.PIECE_SIZE.width / 10, 0) elif row1 < row2: step_point = Point(0, - Piece.PIECE_SIZE.height / 10) else: step_point = Point(0, Piece.PIECE_SIZE.height / 10) animation2 = MovementAnimation(draw_function, piece2, movement.linear_movement, final_position2, step_point) animation1 = MovementAnimation(draw_function, piece1, movement.linear_movement, final_position1, Point(0, 0) - step_point) animation1.start() animation2.start() animations.append(animation1) animations.append(animation2) return animations
def create_board(position: Point, size: Size, columns: int, rows: int, tile_size: Size) -> MatchThreeBoard: if columns < 0: raise AttributeError(f'The number of columns must be positive') if rows < 0: raise AttributeError(f'The number of rows must be positive') offset = Point(int((size.width - tile_size.width * columns) / 2), int((size.height - tile_size.height * rows) / 2)) board = MatchThreeBoard(position.to_tuple(), size.to_tuple()) type_board: List[List[PieceType]] = [] for index in range(0, columns): position = Point(index * tile_size.height, 0) + offset column = Column(position, Size(tile_size.width, tile_size.height * rows)) for row in range(0, rows): if len(type_board) <= row: type_board.append([]) position = Point(0, row * tile_size.width) piece = Piece(position.to_tuple(), tile_size.to_tuple()) is_match = True new_piece = PieceType.BLACK while is_match: new_piece = PieceType.get_random_piece() is_match = src.piece.is_column_combination(board=type_board, column=index, row=row, new_piece=new_piece) is_match = is_match or src.piece.is_row_combination( board=type_board, column=index, row=row, new_piece=new_piece) piece.sprite = GraphicResource(new_piece.value, tile_size) piece.type = new_piece type_board[row].append(new_piece) column.children.append(piece) board.children.append(column) return board
def draw(self, surface: pygame.Surface, offset: Point): container = pygame.Surface(self.__size.to_tuple()) container.set_colorkey(self.__alpha_color) container.fill(self.__alpha_color) x_offset = int((container.get_width() - self.__sprite.size.width) / 2) y_offset = int((container.get_height() - self.__sprite.size.width) / 2) position = Point(x_offset, y_offset) + offset container.blit(self.__sprite.drawable_surface, (x_offset, y_offset)) surface.blit(container, position.to_tuple())
def __init__(self, board: MatchThreeBoard, offset: Point): super().__init__(pygame.MOUSEBUTTONDOWN, (board, offset)) self.__previous: Point = Point(0, 0)
def animate_drop(piece: Piece, final_point: Point, draw_function: Callable[[], None], delay: int = 0) -> MovementAnimation: step_point = Point(0, Piece.PIECE_SIZE.height / 10) return MovementAnimation(draw_function, piece, movement.linear_movement, final_point, step_point, delay)