def __init__(self, app, name: str):
        super().__init__(app, name)
        screen = self.application.screen

        # background
        bg_coord = screen.get_width() / 2 - button.BUTTON_SIZE[0], 2 * label.LABEL_SIZE[1]
        self.bg_rect = pygame.Rect(bg_coord, (2 * button.BUTTON_SIZE[0],
                                              screen.get_height() - 4 * label.LABEL_SIZE[1]))
        frame_coord = self.bg_rect.left + FRAME_WIDTH, self.bg_rect.top + FRAME_WIDTH
        frame_size = 2 * button.BUTTON_SIZE[0] - 2 * FRAME_WIDTH, \
            screen.get_height() - 4 * label.LABEL_SIZE[1] - 2 * FRAME_WIDTH
        self.frame_rect = pygame.Rect(frame_coord, frame_size)

        # button list for menu
        self.B = []
        w = screen.get_width() / 2 - button.BUTTON_SIZE[0] / 2
        button_num = 5
        num_buttons_per_screen = screen.get_height() / 2 / button.BUTTON_SIZE[1]
        offset = (num_buttons_per_screen - button_num) / 2

        h = offset * 2 * button.BUTTON_SIZE[1]
        e = pygame.event.Event(pygame.USEREVENT, {'name': 'moveBoxesGame'})
        self.B.append(button.Button(_('START'), screen, e, (w, h)))

        h += 2 * button.BUTTON_SIZE[1]
        e = pygame.event.Event(pygame.USEREVENT, {'app': self.application,
                                                  'name': 'ChooseLevel0'})
        self.B.append(button.Button(_('LEVELS'), screen, e, (w, h)))

        h += 2 * button.BUTTON_SIZE[1]
        e = pygame.event.Event(pygame.USEREVENT, {'app': self.application, 'name': 'NewLevel'})
        self.B.append(button.Button(_('NEW LEVEL'), screen, e, (w, h)))

        h += 2 * button.BUTTON_SIZE[1]
        e = pygame.event.Event(pygame.USEREVENT, {'app': self.application, 'name': 'Settings'})
        self.B.append(button.Button(_('SETTINGS'), screen, e, (w, h)))

        h += 2 * button.BUTTON_SIZE[1]
        e = pygame.event.Event(pygame.QUIT)
        self.B.append(button.Button(_('EXIT'), screen, e, (w, h)))

        w2 = screen.get_width() / 2 - label.LABEL_SIZE[0] / 2
        self.label = (label.Label(screen, (w2, 0), color=pygame.Color(70, 50, 70)))
    def __init__(self, app, name: str):
        super().__init__(app, name)
        screen = self.application.screen

        # buttons list
        self.B = []

        # labels list
        self.L = []

        w_l = screen.get_width() / 2 - label.LABEL_SIZE[0] / 2
        self.label = (label.Label(screen, (w_l, 0),
                                  color=pygame.Color(70, 50, 70)))

        w = screen.get_width() / 2 - button.BUTTON_SIZE[0] / 2
        h = screen.get_height() / 2 - 3 * button.BUTTON_SIZE[1]
        e = pygame.event.Event(pygame.USEREVENT, {'name': 'Controls'})
        self.B.append(button.Button(_('CONTROLS'), screen, e, (w, h)))

        controls.Controls(app, 'Controls')

        w -= 3 * button.BUTTON_SIZE[0] / 4
        h += 3 * button.BUTTON_SIZE[1]
        e = pygame.event.Event(pygame.USEREVENT, {'name': 'Mode'})
        self.B.append(button.Button(_('MODE'), screen, e, (w, h)))

        self.set_mode = False

        w += 3 * button.BUTTON_SIZE[0] / 2
        h -= button.BUTTON_SIZE[1]
        e = pygame.event.Event(pygame.USEREVENT, {'name': 'Classic'})
        self.B.append(button.Button(_('CLASSIC'), screen, e, (w, h)))

        classic_coord = w - 3 * FRAME_WIDTH, h - 3 * FRAME_WIDTH
        size = button.BUTTON_SIZE[0] + 6 * FRAME_WIDTH, button.BUTTON_SIZE[
            1] + 7 * FRAME_WIDTH
        self.classic_rect = pygame.Rect(classic_coord, size)
        frame_coord = self.classic_rect.left + FRAME_WIDTH, self.classic_rect.top + FRAME_WIDTH
        frame_size = size[0] - 2 * FRAME_WIDTH, size[1] - 2 * FRAME_WIDTH
        self.frame_cl_rect = pygame.Rect(frame_coord, frame_size)

        h += 2 * button.BUTTON_SIZE[1]
        e = pygame.event.Event(pygame.USEREVENT, {'name': 'Easy'})
        self.B.append(button.Button(_('EASY'), screen, e, (w, h)))

        easy_coord = w - 3 * FRAME_WIDTH, h - 3 * FRAME_WIDTH
        self.easy_rect = pygame.Rect(easy_coord, size)
        frame_coord = self.easy_rect.left + FRAME_WIDTH, self.easy_rect.top + FRAME_WIDTH
        self.frame_ea_rect = pygame.Rect(frame_coord, frame_size)

        # button to menu
        w -= 3 * button.BUTTON_SIZE[0] / 2
        w += 3 * button.BUTTON_SIZE[0] / 4
        h += 2 * button.BUTTON_SIZE[1]
        e = pygame.event.Event(pygame.USEREVENT, {'name': '__main__'})
        self.B.append(button.Button(_('BACK'), screen, e, (w, h)))

        # background
        bg_coord = screen.get_width() / 2 - 3 * button.BUTTON_SIZE[0]/2, \
            h - 15 * button.BUTTON_SIZE[1] / 2
        self.bg_rect = pygame.Rect(
            bg_coord,
            (3 * button.BUTTON_SIZE[0], 19 * button.BUTTON_SIZE[1] / 2))
        frame_coord = self.bg_rect.left + FRAME_WIDTH, self.bg_rect.top + FRAME_WIDTH
        frame_size = 3 * button.BUTTON_SIZE[0] - 2 * FRAME_WIDTH, \
            19 * button.BUTTON_SIZE[1] / 2 - 2 * FRAME_WIDTH
        self.frame_rect = pygame.Rect(frame_coord, frame_size)
Exemple #3
0
    def __init__(self, app, name: str, num_added_buttons: int = 0):
        super().__init__(app, name)

        # button list for levels
        self.B = []
        self.gui_B = []
        screen = self.application.screen

        self.button_num_per_col = BUTTONS_NUM_PER_COL
        col = COLUMNS

        num_buttons_per_screen = screen.get_height(
        ) / 2 / button.BUTTON_SIZE[1]
        offset_h = (num_buttons_per_screen - self.button_num_per_col) / 2
        h = offset_h * 2 * button.BUTTON_SIZE[1]

        num_columns_per_screen = screen.get_width(
        ) / 3 / button.BUTTON_SIZE[0] * 2
        offset_w = (num_columns_per_screen - col) / 2
        w = offset_w * 3 * button.BUTTON_SIZE[0] / 2 + button.BUTTON_SIZE[0] / 4

        # background coordinates
        bg_coord = w - button.BUTTON_SIZE[0] / 2, h - button.BUTTON_SIZE[0] / 2
        bg_size = col * 3 * button.BUTTON_SIZE[0] / 2 + button.BUTTON_SIZE[0] / 2,\
            self.button_num_per_col * 2 * button.BUTTON_SIZE[1] + button.BUTTON_SIZE[0]

        self.levels = app.GUIs['moveBoxesGame'].levels
        self.num_added_buttons = num_added_buttons
        buttons_per_page = col * self.button_num_per_col + num_added_buttons
        number_of_buttons = len(self.levels)

        # level buttons
        i = num_added_buttons
        while i < buttons_per_page and i < number_of_buttons:
            level = self.levels[i]
            if level.name.isdigit() and len(level.name) < 4:
                button_name = _('LEVEL ') + level.name
            else:
                button_name = level.name
            e = pygame.event.Event(pygame.USEREVENT, {
                'app': self.application,
                'name': 'moveBoxesGame',
                'lvl': i
            })
            self.B.append(button.Button(button_name, screen, e, (w, h)))
            self.button_num_per_col -= 1
            i += 1
            if self.button_num_per_col:
                h += 2 * button.BUTTON_SIZE[1]
            else:
                w += 3 * button.BUTTON_SIZE[0] / 2
                self.button_num_per_col = BUTTONS_NUM_PER_COL
                h = offset_h * 2 * button.BUTTON_SIZE[1]

        # if number of buttons is too big for one page create a new one
        if i < number_of_buttons:
            w_next = screen.get_width() / 2 + button.BUTTON_SIZE[0] / 4
            h_next = (offset_h +
                      BUTTONS_NUM_PER_COL) * 2 * button.BUTTON_SIZE[1]
            # button to next page
            e = pygame.event.Event(pygame.USEREVENT,
                                   {'name': f'ChooseLevel{i}'})
            self.gui_B.append(
                button.Button(_('NEXT'), screen, e, (w_next, h_next)))
            ChooseLevel(app, f'ChooseLevel{i}', i)
            w_back = screen.get_width(
            ) / 2 - button.BUTTON_SIZE[0] - button.BUTTON_SIZE[0] / 4
        else:
            w_back = screen.get_width() / 2 - button.BUTTON_SIZE[0] / 2

        h_back = (offset_h + BUTTONS_NUM_PER_COL) * 2 * button.BUTTON_SIZE[1]

        # if it is first page back to menu
        if num_added_buttons:
            e = pygame.event.Event(
                pygame.USEREVENT, {
                    'name':
                    f'ChooseLevel{self.num_added_buttons - COLUMNS * BUTTONS_NUM_PER_COL}'
                })
        else:
            e = pygame.event.Event(pygame.USEREVENT, {'name': '__main__'})

        # button to previous page
        self.gui_B.append(button.Button(_('BACK'), screen, e,
                                        (w_back, h_back)))

        # background
        # redraw frame
        if COLUMNS == 1 and i < number_of_buttons:
            bg_coord = bg_coord[0] - button.BUTTON_SIZE[0], bg_coord[1]
            bg_size = bg_size[0] + 2 * button.BUTTON_SIZE[0], bg_size[1]
        self.bg_rect = pygame.Rect(bg_coord, bg_size)

        frame_coord = self.bg_rect.left + FRAME_WIDTH, self.bg_rect.top + FRAME_WIDTH
        frame_size = bg_size[0] - 2 * FRAME_WIDTH, bg_size[1] - 2 * FRAME_WIDTH
        self.frame_rect = pygame.Rect(frame_coord, frame_size)

        self.current_w = w
        self.current_h = h
        self.offset_h = offset_h
        if i == buttons_per_page:
            self.current_w = 0
            self.current_h = 0

        w2 = screen.get_width() / 2 - label.LABEL_SIZE[0] / 2
        self.label = (label.Label(screen, (w2, 0),
                                  color=pygame.Color(70, 50, 70)))
    def __init__(self, app, name: str):
        super().__init__(app, name)

        self.levels = []

        dirname = os.path.dirname(__file__)
        root, dirs, files = next(
            os.walk(os.path.join(dirname, 'levels'), topdown=True))
        for name in files:
            if name.endswith('.lvl'):
                name = name[:-4]
                try:
                    self.levels.append(Level(name))
                except Exception:
                    print(f'Level {name} is not valid.')
        self.levels.sort(key=lambda level: level.order)

        self.current_index = 1
        self.current_level = self.levels[self.current_index]

        # images for game objects
        # default monochrome colors
        self.images = {}
        self.images['background'] = pygame.Surface(
            self.application.screen.get_size())
        self.images['background'].fill((0, 0, 0))
        self.images['free_cell'] = pygame.Surface((128, 128), pygame.SRCALPHA)
        self.images['free_cell'].blit(FREE_CELL_IMAGE, (0, 0))
        self.images['wall'] = pygame.Surface((128, 128), pygame.SRCALPHA)
        self.images['wall'].blit(WALL_IMAGE, (0, 0))
        self.images['box_cell'] = pygame.Surface((128, 128), pygame.SRCALPHA)
        self.images['box_cell'].blit(BOX_CELL_IMAGE, (0, 0))
        self.images['player'] = []
        for img in PLAYER_IMAGE_UP, PLAYER_IMAGE_DOWN, PLAYER_IMAGE_LEFT, PLAYER_IMAGE_RIGHT:
            cur = pygame.Surface((128, 128), pygame.SRCALPHA)
            cur.blit(img, (0, 0))
            self.images['player'].append(cur)
        self.images['box'] = pygame.Surface((128, 128), pygame.SRCALPHA)
        self.images['box'].blit(BOX_IMAGE, (0, 0))
        self.images['grab'] = pygame.Surface((64, 64),
                                             flags=pygame.locals.SRCALPHA)
        self.images['grab'].fill((0, 0, 0, 0))
        pygame.draw.circle(self.images['grab'], (50, 100, 200), (32, 32), 25,
                           4)

        # game variables
        self.player_dir = 1  # default looking down
        self.moves_made = 0
        self.level_finished = False
        self.attempting_grabbing = False
        self.grabbed_box = None

        self.keys = {
            "reset": pygame.locals.K_r,
            "grab": pygame.locals.K_e,
            "next_lvl": pygame.locals.K_PAGEUP,
            "prev_lvl": pygame.locals.K_PAGEDOWN,
            "move": {
                pygame.locals.K_UP: 0,
                pygame.locals.K_DOWN: 1,
                pygame.locals.K_LEFT: 2,
                pygame.locals.K_RIGHT: 3
            }
        }

        self.move_dirs = ((0, -1), (0, 1), (-1, 0), (1, 0))

        # False if player can only push boxes
        self.allow_all_box_moves = True

        # time in seconds to complete one step animation
        self.move_duration = 0.5

        # animation parameters
        self.is_moving = False
        self.moving_time = 0.0
        self.moving_old_poses = {'player': None, 'box': None}

        # buttons
        self.buttons = {}
        screen = self.application.screen

        # button to menu
        button_event = pygame.event.Event(pygame.USEREVENT,
                                          {'name': '__main__'})
        self.buttons['menu'] = button.Button(_('MENU'), screen, button_event,
                                             (0, 0))

        # next level button
        w = screen.get_width() - button.BUTTON_SIZE[0]
        button_event = pygame.event.Event(pygame.USEREVENT, {
            'name': 'moveBoxesGame',
            'lvl': 'next'
        })
        self.buttons['next_lvl'] = button.Button(_('NEXT'), screen,
                                                 button_event, (w, 0))

        # previous level button
        h = 3 * button.BUTTON_SIZE[1] / 2
        button_event = pygame.event.Event(pygame.USEREVENT, {
            'name': 'moveBoxesGame',
            'lvl': 'this'
        })
        self.buttons['reset'] = button.Button(_('RESET'), screen, button_event,
                                              (w, h))

        # restart button
        w -= 5 * button.BUTTON_SIZE[0] / 4
        button_event = pygame.event.Event(pygame.USEREVENT, {
            'name': 'moveBoxesGame',
            'lvl': 'previous'
        })
        self.buttons['prev_lvl'] = button.Button(_('PREVIOUS'), screen,
                                                 button_event, (w, 0))

        # control buttons
        button_size = 35, 35
        button_color = pygame.Color(50, 50, 50)
        font_size = 15

        w = screen.get_width() - 13 * button_size[0] / 4
        h = screen.get_height() - 6 * button_size[1]

        button_event = pygame.event.Event(pygame.locals.KEYDOWN)
        button_event.key = pygame.locals.K_UP
        b_up = button.Button(_('up'), screen, button_event, (w, h),
                             button_size, button_color, font_size)
        self.buttons[0] = b_up

        button_size_1 = 46, 30
        h += button_size[1] + button_size_1[1] / 2
        w -= button_size_1[0] / 2 - button_size[0] / 2
        button_event = pygame.event.Event(pygame.locals.KEYDOWN)
        button_event.key = pygame.locals.K_DOWN
        b_down = button.Button(_('down'), screen, button_event, (w, h),
                               button_size_1, button_color, font_size)
        self.buttons[1] = b_down

        w -= 5 * button_size[0] / 3
        h = screen.get_height() - 5 * button_size[1]
        button_event = pygame.event.Event(pygame.locals.KEYDOWN)
        button_event.key = pygame.locals.K_LEFT
        b_left = button.Button(_('left'), screen, button_event, (w, h),
                               button_size_1, button_color, font_size)
        self.buttons[2] = b_left

        w += 10 * button_size[0] / 3
        button_event = pygame.event.Event(pygame.locals.KEYDOWN)
        button_event.key = pygame.locals.K_RIGHT
        b_right = button.Button(_('right'), screen, button_event, (w, h),
                                button_size_1, button_color, font_size)
        self.buttons[3] = b_right

        button_size_2 = 100, 30
        w = screen.get_width() - 13 * button_size[0] / 4 - (
            button_size_2[0] / 2 - button_size[0] / 2)
        h += 2 * button_size[1]
        button_event = pygame.event.Event(pygame.locals.KEYDOWN)
        button_event.key = pygame.locals.K_e
        b_grab = button.Button(_('grab'), screen, button_event, (w, h),
                               button_size_2, button_color, font_size)
        self.buttons['grab'] = b_grab

        # labels
        self.labels = []

        # current level label
        w = screen.get_width() / 2 - LABEL_SIZE[0] / 2
        self.labels.append(Label(screen, (w, 0)))

        # current moves amount
        h = screen.get_height() - LABEL_SIZE[1]
        self.labels.append(Label(screen, (0, h)))

        # success label
        w = screen.get_width() - LABEL_SIZE[0]
        h = screen.get_height() / 2 - LABEL_SIZE[1] / 2
        self.labels.append(Label(screen, (w, h), font_size=25))
        self.success_str = ''
Exemple #5
0
    def add_level(self, name: str):
        """Add new level to levels list."""

        level = Level(name)
        index = self.application.GUIs['moveBoxesGame'].add_level(level)

        screen = self.application.screen

        if self.current_w and self.current_h:
            if name.isdigit() and len(name) < 4:
                button_name = _('LEVEL ') + name
            else:
                button_name = name
            e = pygame.event.Event(pygame.USEREVENT, {
                'app': self.application,
                'name': 'moveBoxesGame',
                'lvl': index
            })
            self.B.append(
                button.Button(button_name, screen, e,
                              (self.current_w, self.current_h)))
            self.button_num_per_col -= 1

            if len(self.levels
                   ) - self.num_added_buttons < BUTTONS_NUM_PER_COL * COLUMNS:
                if self.button_num_per_col:
                    self.current_h += 2 * button.BUTTON_SIZE[1]
                else:
                    self.current_w += 3 * button.BUTTON_SIZE[0] / 2
                    self.button_num_per_col = BUTTONS_NUM_PER_COL
                    self.current_h = self.offset_h * 2 * button.BUTTON_SIZE[1]
            else:
                self.current_w = 0
                self.current_h = 0
        else:
            e = self.gui_B.pop(-1).event
            w_back = screen.get_width() / 2 - 5 * button.BUTTON_SIZE[0] / 4
            h_next = (self.offset_h +
                      BUTTONS_NUM_PER_COL) * 2 * button.BUTTON_SIZE[1]
            self.gui_B.append(
                button.Button(_('BACK'), screen, e, (w_back, h_next)))
            w_next = screen.get_width() / 2 + button.BUTTON_SIZE[0] / 4

            # button to next page
            e = pygame.event.Event(pygame.USEREVENT, {
                'app': self.application,
                'name': f'ChooseLevel{index}'
            })
            self.gui_B.append(
                button.Button(_('NEXT'), screen, e, (w_next, h_next)))
            ChooseLevel(self.application, f'ChooseLevel{index}', index)

            # redraw frame
            if COLUMNS == 1:
                bg_coord = self.bg_rect.left - button.BUTTON_SIZE[
                    0], self.bg_rect.top
                bg_size = self.bg_rect.width + 2 * button.BUTTON_SIZE[
                    0], self.bg_rect.height
                self.bg_rect = pygame.Rect(bg_coord, bg_size)

                frame_coord = self.bg_rect.left + FRAME_WIDTH, self.bg_rect.top + FRAME_WIDTH
                frame_size = bg_size[0] - 2 * FRAME_WIDTH, bg_size[
                    1] - 2 * FRAME_WIDTH
                self.frame_rect = pygame.Rect(frame_coord, frame_size)