from random import sample import pygame from coords import Coords from common import DrawableGameObject, FONT_NAME from maze import get_maze_sz class Coin(DrawableGameObject): """объект монетки""" def __init__( self, coords: Coords, parent: DrawableGameObject, assets: dict | None = None, ): super().__init__(coords, parent, assets) self._surface = pygame.image.load(self.assets["coin.png"]) self.rect = self.surface.get_rect() self.rect.topleft = coords # уменьшаем размер монетки sf = Coords(0.7, 0.7) self._surface, self.rect = self.scene.scale_box(self.surface, self.rect, sf) def draw(self): self.parent.surface.blit(self.surface, self.rect) @property def bounding_rect(self) -> pygame.Rect: new_rect = self.surface.get_bounding_rect() new_rect.center = self.rect.center return new_rect class Coins(DrawableGameObject): """объект коллекции монеток""" def __init__( self, parent: DrawableGameObject, maze: list[list[int]], box_sz: Coords, count: int, assets: dict | None = None, ): super().__init__(Coords.zero(), parent, assets) self.box_sz = box_sz self._capacity = count free_points = [] excluded = Coords(0, 1), get_maze_sz(maze) - Coords(1, 2) for i, row in enumerate(maze): for j, item in enumerate(row): p = Coords(j, i) if item < 1 and p not in excluded: free_points.append(p) continue coin_points = sample(free_points, min(count, len(free_points))) self.coins = [ Coin(point.transform(box_sz), self, self.assets) for point in coin_points ] self.collected_coins = [] # Надпись, если все монетки собраны font = pygame.font.SysFont(FONT_NAME, 30) text = "Все монетки собраны!" self.done_txt = font.render(text, 1, "#050366e3") self.done_txt_rect = self.done_txt.get_rect() self.done_txt_rect.topleft = Coords(10, 10) @property def capacity(self) -> int: return self._capacity @property def coins_left(self) -> int: return len(self.coins) @property def coins_collected(self) -> int: return self.capacity - self.coins_left @property def all_collected(self) -> int: return self.coins_left == 0 def draw(self): for coin in self.collected_coins: coin.draw() for coin in self.coins: coin.draw() if self.all_collected: self.parent.surface.blit(self.done_txt, self.done_txt_rect) def add_to_collected(self, coin: Coin): last_pos = Coords(10, 10) if self.collected_coins: last_pos = Coords(*self.collected_coins[-1].rect.topright) last_pos -= Coords(coin.rect.width // 2, 0) coin.coords = last_pos self.collected_coins.append(coin) def collect(self, actor: DrawableGameObject): mined = [*filter(lambda coin: coin.overlap(actor.rect, actor.mask), self.coins)] for coin in mined: self.coins.remove(coin) self.add_to_collected(coin)