Example #1
0
 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
Example #8
0
    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))