class Intro: def __init__(self, screen: pg.Surface): pg.mixer.init() self.screen = screen self.playing = True self.slides_sheet = Sheet(str(PurePath(PATH_IMAGES).joinpath('slidesheet.png'))) self.slides = [self.slides_sheet.get_image(0, HEIGHT * i, WIDTH, HEIGHT) for i in range(0, 3)] self.voice_clips = [pg.mixer.Sound(str(PurePath(PATH_VOICES).joinpath(i))) for i in os.listdir(str(PurePath(PATH_VOICES)))] volume = get_volume() self.voice_clips[0].set_volume(volume) self.voice_clips[1].set_volume(volume) self.voice_clips[2].set_volume(volume) self.durations = [i.get_length() for i in self.voice_clips] self.durations[0] += 1.5 self.start_time = pg.time.get_ticks() self.index = 0 self.once = True def play(self): current_time = (pg.time.get_ticks() - self.start_time) / 1000 if current_time > self.durations[self.index]: self.index += 1 self.start_time = pg.time.get_ticks() self.once = True if self.index == 3: self.playing = False self._played() return if self.once: self.voice_clips[self.index].play() self.once = False self.screen.blit(self.slides[self.index], (0, 0)) pg.display.flip() def _played(self): import json file = str(PurePath(PATH_PROJECT).joinpath('data.json')) with open(file, 'r') as f: data = json.load(f) data['intro_played'] = True with open(file, 'w') as f: json.dump(data, f)
class Home: """ Represents the main menu page. The main menu page contains buttons which lead to playing the game, about page, options page and exiting. """ def __init__(self, screen: pg.Surface, paused: bool = False): """ Constructor for the main menu page. """ self.screen = screen self.paused = paused # SCREEN: 1280x720px = WxH # devided by 5 parts horizontally - W/5 = 256px (slice) # devided by 8 parts vertically - H/8 = 90px (segment) self.slice = WIDTH // 5 # 256px self.segment = HEIGHT // 8 # 90px self.air = self.space = 10 # px self.shift = 20 # px self.sheet = Sheet(str(PurePath(PATH_BUTTONS).joinpath(BUTTONSHEET))) if self.paused: self.background = load(str(PurePath(PATH_BACKGROUNDS).joinpath(BACKGROUND_3))).convert_alpha() else: self.background = load(str(PurePath(PATH_BACKGROUNDS).joinpath(BACKGROUND))).convert_alpha() self.buttons_hover_states = {'play': False, 'options': False, 'about': False, 'exit': False, 'gitlab': False} self.buttons_sprites = { 'play': self.sheet.get_image(0, 0, 384, 70, True), 'options': self.sheet.get_image(0, 70, 320, 70, True), 'about': self.sheet.get_image(0, 140, 320, 70, True), 'exit': self.sheet.get_image(0, 210, 320, 70, True), 'gitlab': self.sheet.get_image(320, 70, 100, 100, True), 'gitlab_h': self.sheet.get_image(320, 170, 100, 100, True)} # LOGO: 768x360px # horizontal - logo takes 3 parts out of 5 - W/5 * 3 = 768px # vertical - logo takes half of H - H/2 = 360px self.logo_rect = pg.Rect(self.slice, 0, self.slice * 3, HEIGHT / 2) self.logo_image = load(str(PurePath(PATH_IMAGES).joinpath(LOGO))).convert_alpha() # PLAY BUTTON (larger) 384x70px # horizontal - one part and half of 5 = W/5 * 1.5 = 384px # vertical - 7 parts of 9 (of the segment) = S/9 * 7 = 70px # (10px for the air on top and the bottom) self.play_button_rect = \ pg.Rect(self.space, self.segment * 4 + self.air, self.slice * 1.5, self.segment - (self.air * 2)) # other buttons 320*70px # horizontal - one part and quarter of 5 = W/5 * 1.25 = 320px # vertical - 7 parts of 9 (of the segment) = S/9 * 7 = 70px # (10px for the air on top and the bottom) self.other_button_rect = \ pg.Rect(self.space, self.segment * 5, self.slice * 1.25, self.segment - (self.air * 2)) self.gitlab_button_rect = pg.Rect(WIDTH - 100 - 20, HEIGHT - 100 - 20, 200, 200) self.buttons_dict = {'options': 5, 'about': 6, 'exit': 7} self.sound = HOVER_SOUND self.sound.set_volume(get_volume()) self.cursor = load(str(PurePath(PATH_CURSORS).joinpath(CURSOR))).convert_alpha() self.cursor2 = load(str(PurePath(PATH_CURSORS).joinpath(CURSOR_HOVER))).convert_alpha() self.once = True def draw(self)-> None: """ Unifying drawing method - draws every element of the main menu. """ x, y = pg.mouse.get_pos() self._draw_background() self._draw_play_button(x, y) self._draw_gitlab_button(x, y) self._draw_other_buttons(x, y) self._play_sound() self._draw_cursor(x, y) pg.display.update() def _draw_background(self)->None: """ Bliting the background image and the game logo on the screen. """ self.screen.blit(self.background, (0, 0)) self.screen.blit(self.logo_image, self.logo_rect) def _draw_cursor(self, x: int, y: int)->None: """ Bliting the cursor on the screen. Classical cursor and finger cursor (if any hoverable element is hovered). """ if any(self.buttons_hover_states.values()): self.screen.blit(self.cursor2, (x, y)) else: self.screen.blit(self.cursor, (x, y)) def _draw_play_button(self, x: int, y: int)-> None: """ Bliting the play button on the screen. Shifting to the right if it is hovered. """ self.play_button_rect.top = self.segment * 4 self.play_button_rect.left = self.space hovered = self._hovered(x, y, self.play_button_rect) if hovered: self.buttons_hover_states['play'] = True self.play_button_rect.left = self.shift self.screen.blit(self.buttons_sprites['play'], self.play_button_rect) else: self.buttons_hover_states['play'] = False self.play_button_rect.left = self.space self.screen.blit(self.buttons_sprites['play'], self.play_button_rect) def _draw_other_buttons(self, x, y): """ Iterating through other buttons and bliting them on the screen. """ for key in self.buttons_dict.keys(): self._draw_other_button(x, y, key) def _draw_other_button(self, x: int, y: int, button: str)-> None: """ Bliting given button on the screen. Shifting to the right if it is hovered. """ self.other_button_rect.top = self.segment * self.buttons_dict[button] hovered = self._hovered(x, y, self.other_button_rect) if hovered: self.buttons_hover_states[button] = True self.other_button_rect.left = self.shift self.screen.blit(self.buttons_sprites[button], self.other_button_rect) else: self.buttons_hover_states[button] = False self.other_button_rect.left = self.space self.screen.blit(self.buttons_sprites[button], self.other_button_rect) def _draw_gitlab_button(self, x: int, y: int)-> None: """ Bliting the GitLab button (link). Bliting hovered version of the button if it is hovered. """ hovered = self._hovered(x, y, self.gitlab_button_rect) if hovered: self.buttons_hover_states['gitlab'] = True self.screen.blit(self.buttons_sprites['gitlab_h'], self.gitlab_button_rect) else: self.buttons_hover_states['gitlab'] = False self.screen.blit(self.buttons_sprites['gitlab'], self.gitlab_button_rect) def _play_sound(self)-> None: """ Playing the hover sound if any hoverable element is hovered. """ if not any(self.buttons_hover_states.values()): self.once = True elif self.once: self.sound.play() self.once = False def update_volume(self)->None: """ Updating the power of the volume if needed. """ self.sound.set_volume(get_volume()) @staticmethod def _hovered(x: int, y: int, button: pg.Rect)-> bool: """ Wrapper for collidepoint (checks if point is in pygame.Rect object). """ return button.collidepoint(x, y) @staticmethod def open_gitlab()-> None: """ Opens the gitlab link in the browser. """ wb.open(GIT_LAB_LINK)