def _draw_current_state(self): text_color = (0, 0, 0) if self.clicked: self.image = draw_cell(self.width, self.height, convex=False) elif self.enabled: self.image = draw_cell(self.width, self.height) else: self.image.fill(DARK_GRAY) pg.draw.rect(self.image, MAIN_GRAY, (2, 2, self.rect.w - 3, self.rect.h - 3)) text_color = DARK_GRAY text = self.font.render(self.label, True, text_color) x, y = self.width // 2 - text.get_width( ) // 2, self.height // 2 - text.get_height() // 2 self.image.blit(text, (x, y))
def release(self): res = False if self.clicked: res = True self.clicked = False self.image = draw_cell(self.size, self.size) if not self._lock_state: self.change_state(GameStates.IDLE) return res
def __init__(self, x, y, width, height, start_value=0, *groups): self.__value = start_value self.changed = True self.image = draw_cell(width, height, 2, False) self.rect = pg.Rect(x, y, width, height) self.numbers = { str(num): load_image(f'seven segment/{num}.png') for num in range(10) } super().__init__(*groups)
def __init__(self, x, y, cell_size, left_indent, top_indent, *groups): super().__init__(*groups) self.size = cell_size self.x, self.y = x, y x, y = left_indent + y * cell_size, top_indent + x * cell_size self.content = 0 self.content_image = None self.rect = pg.rect.Rect(x, y, cell_size, cell_size) self.image = draw_cell(cell_size, cell_size) self.is_opened = False self.mark = None
def set_mark(self): if not self.is_opened: if self.mark is None: self.mark = 'F' elif self.mark == 'F': self.mark = 'Q' else: self.mark = None self.image = draw_cell(self.size, self.size) if self.mark is not None: self.image.blit(load_image(f'{self.mark}.png'), (0, 0))
def __init__(self, x, y, size, *groups): self.size = size self.image = draw_cell(size, size) self.rect = pg.Rect(x, y, size, size) self._lock_state = False self.states: dict[GameStates, pg.Surface] = { state: load_image(f'states/{state.value}.png') for state in GameStates } self.state_size = self.states[GameStates.IDLE].get_rect().w self.change_state(GameStates.IDLE) super().__init__(*groups) self.clicked = False
def click(self, mouse_pos): if self.rect.collidepoint(mouse_pos): self._lock_state = False self.image = draw_cell(self.size, self.size, convex=False) self.change_state(GameStates.IDLE) self.clicked = True
def init_screens(self): field_w, field_h = self.game_preset.field_size font = pg.font.Font('assets/lcd.ttf', 20) w = self.layout.left_indent * 2 + self.layout.cell_size * field_w h = self.layout.top_indent + self.layout.cell_size * field_h + \ self.layout.left_indent + self.layout.menubar_height self.screen = pg.display.set_mode((w, h)) self.screens = {name: pg.Surface((w, h)) for name in Screens} pg.display.set_caption('Minesweeper') panel_y = \ self.layout.left_indent - self.layout.field_indent + ( self.layout.top_indent - 25) / 2 - self.layout.indicator_size // 2 + \ self.layout.menubar_height indicator = Indicator( self.layout.left_indent + self.layout.cell_size * field_w / 2 - self.layout.indicator_size // 2, panel_y, self.layout.indicator_size) mine_counter = Counter( self.layout.left_indent * 2 - self.layout.field_indent, panel_y, self.layout.counter_width, self.layout.indicator_size, self.game_preset.mines_count) self.timer = Counter( field_w * self.layout.cell_size + self.layout.left_indent - self.layout.field_indent * 2 - self.layout.counter_width, panel_y, self.layout.counter_width, self.layout.indicator_size) self.panel = pg.sprite.Group(indicator, mine_counter, self.timer) self.field = Field(field_w, field_h, self.layout.left_indent, self.layout.top_indent + self.layout.menubar_height, self.layout.cell_size, indicator, mine_counter, self.game_preset.mines_count) button_font = pg.font.Font('assets/lcd.ttf', 16) settings_button = MenuButton( 0, 0, self.layout.menubar_height, 'Settings', button_font, on_click=lambda: self.change_screen(Screens.SETTINGS)) help_button = MenuButton( settings_button.rect.w, 0, self.layout.menubar_height, 'Help', button_font, on_click=lambda: self.change_screen(Screens.HELP)) self.menu_bar = pg.sprite.Group(settings_button, help_button) self.screens[Screens.MAIN].fill(MAIN_GRAY) self.screens[Screens.MAIN].blit( draw_cell( field_w * self.layout.cell_size + self.layout.field_indent * 2, field_h * self.layout.cell_size + self.layout.field_indent * 2, self.layout.field_indent, False), (self.layout.left_indent - self.layout.field_indent, self.layout.top_indent - self.layout.field_indent + self.layout.menubar_height)) self.screens[Screens.MAIN].blit( draw_cell(field_w * self.layout.cell_size + self.layout.field_indent * 2, self.layout.top_indent - 25, convex=False), (self.layout.left_indent - self.layout.field_indent, self.layout.left_indent - self.layout.field_indent + self.layout.menubar_height)) pg.draw.rect(self.screens[Screens.MAIN], 'white', (0, 0, w, self.layout.menubar_height)) if self.settings_layout is not None: values = [ i.get_value(str) for i in self.settings_layout if isinstance(i, TextInput) ] else: values = [''] * 3 self.settings_layout = pg.sprite.Group() r = 8 x0 = w / 2 - 150 y0 = h / 2 - 200 x = x0 + self.layout.field_indent + 2 * r + 5 header_font = pg.font.Font('assets/lcd.ttf', 24) header = Label(x0 + self.layout.left_indent, y0 + self.layout.left_indent, 'Difficulty', header_font, self.settings_layout) y = header.rect.y + header.rect.h + 10 if len(RADIO_GROUP) > 0: checked_buttons = [b.checked for b in RADIO_GROUP.sprites()] else: checked_buttons = [True] + [False] * len(self.presets) RADIO_GROUP.empty() for (name, preset), checked in zip(self.presets.items(), checked_buttons): button = RadioButton(x0 + self.layout.field_indent, y, r, self.settings_layout, checked=checked) Label(x, y, f'{name.title()} ({"×".join(map(str, preset.field_size))}, ' f'{preset.mines_count} mines)', font, self.settings_layout, assigned_item=button) y += r * 2 + 10 button = RadioButton(x0 + self.layout.field_indent, y, r, self.settings_layout, checked=checked_buttons[-1]) Label(x, y, 'Custom', font, self.settings_layout, assigned_item=button) y += r * 2 + 10 sep, shift = 70, 10 self.width_input = TextInput(x + sep, y, 60, 30, font, IntValidator(9, 24), handle_change, self.settings_layout) self.width_input.set_value(values[0]) Label(x, y + shift, 'Width:', font, self.settings_layout, assigned_item=self.width_input) self.height_input = TextInput(x + sep, y + 40, 60, 30, font, IntValidator(9, 24), handle_change, self.settings_layout) self.height_input.set_value(values[1]) Label(x, y + 40 + shift, 'Height:', font, self.settings_layout, assigned_item=self.height_input) self.mines_count_input = TextInput(x + sep, y + 80, 60, 30, font, IntValidator(10, 99), lambda: None, self.settings_layout) self.mines_count_input.set_value(values[2]) Label(x, y + 80 + shift, 'Mines:', font, self.settings_layout, assigned_item=self.mines_count_input) Button(x0 + 200, y + 150, 75, 30, 'OK', font, self.settings_layout, on_click=lambda: self.change_screen(Screens.MAIN)) self.screens[Screens.SETTINGS].fill(MAIN_GRAY) self.screens[Screens.HELP].fill(MAIN_GRAY) self.help_layout = pg.sprite.Group() help_header = Label(x0 + self.layout.left_indent, y0 + self.layout.left_indent, 'Help', header_font, self.help_layout) y = y0 + self.layout.left_indent + help_header.rect.h + 15 with open('docs/help.txt') as f: for line in f.read().split('\n'): label = Label(x0 + self.layout.left_indent, y, line, font, self.help_layout) y += label.rect.h + 5 y += 30 little_font = pg.font.Font('assets/lcd.ttf', 16) Label(x0 + self.layout.left_indent, y, '© dQw4w9WgXcQ Games, 2021', little_font, self.help_layout) y += 20 Label(x0 + self.layout.left_indent, y, 'Original game made by Microsoft', little_font, self.help_layout) Button(w - x0 - 150 - self.layout.left_indent, y0 + self.layout.left_indent - self.layout.field_indent, 150, 30, 'Back to game →', font, self.help_layout, on_click=lambda: self.change_screen(Screens.MAIN))