import sys import time import pygame from .screen import Screen from .text import Text, Title SCREEN_BG_COLOR = (50, 50, 50) MOB_ASSETS = { 'Yanaar': 'assets/orc.png', 'Ulnarain': 'assets/orc2.jpg', 'Skroll': 'assets/potato_man.jpg', } PLAYER_ASSET = 'assets/succube.png' class PygameUi: def __init__(self): self.screen = Screen() self.show_title() def show_title(self): title = Title().set_position(center=self.screen.rect.center) space = Text('press space').set_position(midtop=title.rect.midbottom) loop_start = time.time() loop = True while loop: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: loop = False self.screen.surface.fill(SCREEN_BG_COLOR) title.show(self.screen.surface) loop_time = time.time() - loop_start if loop_time % 2.0 > 1.0: space.show(self.screen.surface) self.screen.refresh() def empty_room(self): margin = 16 inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2)) title = Text('Room empty', font_size=48).set_position(center=inner_box.center) instructions = Text('Press enter to continue', font_size=24) instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom) loop = True while loop: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN): loop = False self.screen.surface.fill(SCREEN_BG_COLOR) title.show(self.screen.surface) instructions.show(self.screen.surface) self.screen.refresh() def meet_mob(self, mob): margin = 16 inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2)) title = Text('Mob in the room', font_size=48).set_position(midtop=inner_box.midtop) instructions = Text('Press enter to continue', font_size=24) instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom) spec_margin = 16 spec_box = pygame.Rect( inner_box.left, title.rect.bottom + spec_margin, inner_box.width, instructions.rect.top - title.rect.bottom - (spec_margin * 2) ) img = pygame.image.load(MOB_ASSETS[mob.name]) img_rect = img.get_rect().fit(pygame.Rect(0, 0, spec_box.height, spec_box.height)) img = pygame.transform.smoothscale(img, img_rect.size) img_rect = img.get_rect(midleft=spec_box.midleft) props_box = pygame.Rect( img_rect.right, spec_box.top, spec_box.width - img_rect.width, spec_box.height, ) mob_name = Text(mob.name, font_size=36) mob_name = mob_name.set_position(midtop=props_box.midtop) mob_pv = Text(f"PV: {mob.current_pv}/{mob.max_pv}") mob_pv = mob_pv.set_position(top=mob_name.rect.bottom + 36, left=props_box.left + 16) mob_strength = Text(f"Force: {mob.strength}") mob_strength = mob_strength.set_position(top=mob_pv.rect.bottom + 24, left=props_box.left + 16) mob_protection = Text(f"Protection: {mob.protection}") mob_protection = mob_protection.set_position(top=mob_strength.rect.bottom + 24, left=props_box.left + 16) mob_speed = Text(f"Vitesse: {mob.speed}") mob_speed = mob_speed.set_position(top=mob_protection.rect.bottom + 24, left=props_box.left + 16) texts = [ title, mob_name, mob_pv, mob_strength, mob_protection, mob_speed, instructions, ] loop = True while loop: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN): loop = False self.screen.surface.fill(SCREEN_BG_COLOR) self.screen.surface.blit(img, img_rect) for text in texts: text.show(self.screen.surface) self.screen.refresh() def player_dead(self): margin = 16 inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2)) title = Text('You are dead', font_size=48).set_position(center=inner_box.center) instructions = Text('Press enter to continue', font_size=24) instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom) loop = True while loop: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN): loop = False self.screen.surface.fill(SCREEN_BG_COLOR) title.show(self.screen.surface) instructions.show(self.screen.surface) self.screen.refresh() def mob_dead(self, mob): margin = 16 inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2)) title = Text('You win', font_size=48).set_position(center=inner_box.center) instructions = Text('Press enter to continue', font_size=24) instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom) loop = True while loop: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN): loop = False self.screen.surface.fill(SCREEN_BG_COLOR) title.show(self.screen.surface) instructions.show(self.screen.surface) self.screen.refresh() def run_away(self): margin = 16 inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2)) title = Text('You are running away', font_size=48).set_position(center=inner_box.center) for _ in range(60): # 60 tick at 60fps => loop for 1sec for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN): loop = False self.screen.surface.fill(SCREEN_BG_COLOR) title.show(self.screen.surface) self.screen.refresh() def leave(self, player): title = Text(f'Goodbye {player.name}', font_size=48).set_position(center=self.screen.surface.get_rect().center) for _ in range(60): # 60 tick at 60fps => loop for 1sec for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() self.screen.surface.fill(SCREEN_BG_COLOR) title.show(self.screen.surface) self.screen.refresh() def select_player(self, player): margin = 16 inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2)) title = Text('Player selection', font_size=48).set_position(midtop=inner_box.midtop) instructions = Text('Press enter to continue', font_size=24) instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom) spec_margin = 16 spec_box = pygame.Rect( inner_box.left, title.rect.bottom + spec_margin, inner_box.width, instructions.rect.top - title.rect.bottom - (spec_margin * 2) ) img = pygame.image.load(PLAYER_ASSET) img_rect = img.get_rect().fit(pygame.Rect(0, 0, spec_box.height, spec_box.height)) img = pygame.transform.smoothscale(img, img_rect.size) img_rect = img.get_rect(midleft=spec_box.midleft) props_box = pygame.Rect( img_rect.right, spec_box.top, spec_box.width - img_rect.width, spec_box.height, ) player_name = Text(player.name, font_size=36) player_name = player_name.set_position(midtop=props_box.midtop) player_pv = Text(f"PV: {player.current_pv}/{player.max_pv}") player_pv = player_pv.set_position(top=player_name.rect.bottom + 36, left=props_box.left + 16) player_strength = Text(f"Force: {player.strength}") player_strength = player_strength.set_position(top=player_pv.rect.bottom + 24, left=props_box.left + 16) player_protection = Text(f"Protection: {player.protection}") player_protection = player_protection.set_position( top=player_strength.rect.bottom + 24, left=props_box.left + 16) player_speed = Text(f"Vitesse: {player.speed}") player_speed = player_speed.set_position(top=player_protection.rect.bottom + 24, left=props_box.left + 16) texts = [ title, player_name, player_pv, player_strength, player_protection, player_speed, instructions, ] loop = True while loop: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN): loop = False self.screen.surface.fill(SCREEN_BG_COLOR) self.screen.surface.blit(img, img_rect) for text in texts: text.show(self.screen.surface) self.screen.refresh() def entering_room(self, room_name): margin = 16 inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2)) title = Text(f'Room {room_name + 1}', font_size=48).set_position(center=inner_box.center) instructions = Text('Press enter to continue', font_size=24) instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom) loop = True while loop: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN): loop = False self.screen.surface.fill(SCREEN_BG_COLOR) title.show(self.screen.surface) instructions.show(self.screen.surface) self.screen.refresh() def last_room(self): margin = 16 inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2)) title = Text('End of level', font_size=48).set_position(center=inner_box.center) instructions = Text('Press enter to continue', font_size=24) instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom) loop = True while loop: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN): loop = False self.screen.surface.fill(SCREEN_BG_COLOR) title.show(self.screen.surface) instructions.show(self.screen.surface) self.screen.refresh() def entering_donjon(self, level): margin = 16 inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2)) title = Text(f'Level 1 - {len(level.rooms)} rooms', font_size=48).set_position(center=inner_box.center) instructions = Text('Press enter to continue', font_size=24) instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom) loop = True while loop: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN): loop = False self.screen.surface.fill(SCREEN_BG_COLOR) title.show(self.screen.surface) instructions.show(self.screen.surface) self.screen.refresh() def action_menu(self, actions_autorisees): texts = [Text(action.libelle) for n, action in enumerate(actions_autorisees)] arrow = Text('> ') action_index = 0 margin = 16 inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2)) title = Text('Select action', font_size=48).set_position(midtop=inner_box.midtop) instructions = Text('Press enter to continue; Press up or down to move arrow', font_size=24) instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom) action_box = pygame.Rect(inner_box.left + 64, title.rect.bottom + 64, inner_box.width, inner_box.height) last_bottom = action_box.top for text in texts: text.set_position(left=action_box.left, top=last_bottom) last_bottom = text.rect.bottom + 24 while True: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN): return actions_autorisees[action_index] elif event.key == pygame.K_DOWN: action_index = min(action_index + 1, len(actions_autorisees) - 1) elif event.key == pygame.K_UP: action_index = max(action_index - 1, 0) self.screen.surface.fill(SCREEN_BG_COLOR) title.show(self.screen.surface) for text in texts: text.show(self.screen.surface) arrow.set_position(midright=texts[action_index].rect.midleft).show(self.screen.surface) instructions.show(self.screen.surface) self.screen.refresh() def fight_pvs(self, player, mob, pvs): margin = 16 inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2)) title = Text('Fight', font_size=48).set_position(midtop=inner_box.midtop) player_img = pygame.image.load(PLAYER_ASSET) player_img_rect = player_img.get_rect().fit(pygame.Rect(0, 0, 128, 128)) player_img = pygame.transform.smoothscale(player_img, player_img_rect.size) player_img_rect = player_img.get_rect(left=inner_box.left + 48, centery=inner_box.centery) mob_img = pygame.image.load(MOB_ASSETS[mob.name]) mob_img_rect = mob_img.get_rect().fit(pygame.Rect(0, 0, 128, 128)) mob_img = pygame.transform.smoothscale(mob_img, mob_img_rect.size) mob_img_rect = mob_img.get_rect(right=inner_box.right - 48, centery=inner_box.centery) init_fight = [{ 'player': player.max_pv, 'mob': mob.max_pv, }] all_pvs = init_fight + pvs for pv in all_pvs: for _ in range(60): # 60 tick at 60fps => loop for 1sec for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() self.screen.surface.fill(SCREEN_BG_COLOR) title.show(self.screen.surface) self.screen.surface.blit(player_img, player_img_rect) self.screen.surface.blit(mob_img, mob_img_rect) (Text(f"{pv['player']}/{player.max_pv}", font_size=36) .set_position(midtop=player_img_rect.midbottom) .show(self.screen.surface)) (Text(f"{pv['mob']}/{mob.max_pv}", font_size=36) .set_position(midtop=mob_img_rect.midbottom) .show(self.screen.surface)) self.screen.refresh()