def pause_screen(screen: pygame.Surface, font: pygame.font): """Obscurcis l'écran pour indiquer à l'utilisateur que le programme est en pause Parameters ---------- screen: La fenêtre du programme font: :mod:`pygame.font` La police à utiliser """ color = (10, 10, 10) purple_image = pygame.Surface(SETTINGS.screen_size) purple_image.set_colorkey((0, 0, 0)) purple_image.set_alpha(150) pygame.draw.rect(purple_image, color, purple_image.get_rect(), 0) screen.blit(purple_image, (0, 0)) x = SETTINGS.screen_size[0] / 2 y = SETTINGS.screen_size[1] * 0.1 text1 = font.render("Programme en pause", True, (255, 255, 255), None) text2 = font.render("Appuyez sur P pour relancer", True, (255, 255, 255), None) rect1 = text1.get_rect() rect2 = text2.get_rect() screen.blit(text1, (x - rect1.width / 2, y - rect1.height / 2)) screen.blit(text2, (x - rect2.width / 2, y + (rect1.height * 1.2) - rect2.height / 2))
def update(self, font: pygame.font) -> None: """ Updates the Tab surface :param font: Font to be used to render the text :return: None """ self.fill(TAB_BACKGROUND) # Draw each tab pygame.draw.rect(self, TAB_BORDER, self.__sects[0], 0 if self.selected_equipment else 2) pygame.draw.rect(self, TAB_BORDER, self.__sects[1], 0 if not self.selected_equipment else 2) # Draw text self.blit( font.render( "Equipment", True, TAB_SELECTED_TEXT_COLOUR if self.selected_equipment else TEXT_COLOUR), ((self.__sects[0].w // 2) - (font.size("Equipment")[0] // 2), (self.__sects[0].y + (self.__sects[0].h // 2)) - (font.size("Equipment")[1] // 2))) self.blit( font.render( "Attributes", True, TAB_SELECTED_TEXT_COLOUR if not self.selected_equipment else TEXT_COLOUR), (self.__sects[1].x + ((self.__sects[1].w // 2) - (font.size("Attributes")[0] // 2)), (self.__sects[1].y + (self.__sects[1].h // 2)) - (font.size("Equipment")[1] // 2)))
def general_stats(screen: pygame.Surface, font: pygame.font, clock: pygame.time.Clock, gen_nbr: int, cars_nbr: int, start_time: float): """Affiche les informations générales à l'écran Ces informations sont constituées des FPS actuels, du numéro de génération, du nombre de voitures restantes, et du temps passé depuis le début de la génération. Parameters ---------- screen: La fenêtre du programme font: :mod:`pygame.font` La police à utiliser clock: L'horloge interne de Pygame gen_nbr: Le numéro de génération cars_nbr: Le nombre de voitures restantes start_time: Timestamp du début de la génération """ texts = list() bg = SETTINGS.colors['background'] text_color = SETTINGS.colors['text'] # FPS t = clock.get_rawtime() nbr = 0 if t == 0 else round(1000 / t) if nbr < 7: # color = (255, 0, 0) color = SETTINGS.colors['fps-colors'][0] elif nbr < 12: # color = (255, 153, 0) color = SETTINGS.colors['fps-colors'][1] else: # color = (51, 102, 0) color = SETTINGS.colors['fps-colors'][2] fps = font.render("FPS: " + str(nbr), True, color, bg) texts.append(fps) # Generation Nbr if gen_nbr is not None: generations = font.render("Génération " + str(gen_nbr), True, text_color, bg) texts.append(generations) # Alive networks if cars_nbr is not None: s = "s" if cars_nbr > 1 else "" cars = font.render("{0} voiture{1} restante{1}".format(cars_nbr, s), True, text_color, bg) texts.append(cars) # Elapsed time t = round(time.time() - start_time, 2) elapsed_time = font.render("Temps : " + str(t), True, text_color, bg) texts.append(elapsed_time) # Display them all x = ceil(10 * SETTINGS.scale_x) y = ceil(5 * SETTINGS.scale_y) for e, t in enumerate(texts): screen.blit(t, (x, y + ceil(e * 15 * SETTINGS.scale_y)))
def car_specs(screen: pygame.Surface, font: pygame.font, network: Network): """Affiche des informations sur la voiture sélectionnée Ces informations contionnent le score actuel de la voiture, sa direction et sa vitesse Parameters ---------- screen: La fenêtre du programme font: :mod:`pygame.font` La police utilisée network: Le réseau neuronal dont les informations seront extraites """ direction = round(network.direction, 3) engine = round(network.engine, 3) color = SETTINGS.colors["dead-stats"] if network.dead else SETTINGS.colors[ "text"] bg = SETTINGS.colors["background"] _, y = SETTINGS.screen_size x = ceil(7 * SETTINGS.scale_x) # Score score = network.car.get_score() text3 = font.render(f"Score: {score}", True, color, bg) y2 = y - ceil(50 * SETTINGS.scale_y) screen.blit(text3, (x, y2)) # Direction y2 = y - ceil(35 * SETTINGS.scale_y) text1 = font.render(f"Direction: {direction}", True, color, bg) screen.blit(text1, (x, y2)) # Vitesse y2 = y - ceil(20 * SETTINGS.scale_y) text2 = font.render(f"Engine: {engine}", True, color, bg) screen.blit(text2, (x, y2))
def loadChessboardDescription(self, font: pygame.font) -> List: row_array = [] for index, letter in enumerate(ROW_DESCRIPTION): row_array.append((font.render(letter, True, COLOUR_RED), ROW_DESCRIPTION_INDEX_X + index * TILE_WIDTH, ROW_DESCRIPTION_INDEX_Y)) col_array = [] for index, number in enumerate(COL_DESCRIPTION): col_array.append((font.render(number, True, COLOUR_RED), COL_DESCRIPTION_INDEX_X, COL_DESCRIPTION_INDEX_Y + index * TILE_HEIGHT)) return [col_array, row_array]
def draw_text(text: str, font: pygame.font, color: Tuple[int, int, int], width: int, background: Tuple[int, int, int] = None): """ Renders a pygame surface containing word-wrapped text Args: text: the text to be rendered font: the pygame font object to use width: the maximum width of the text block (height is considered unlimited) Returns: Pygame surface containing the rendered text """ if width == 0: return font.render(text, True, color, background) lines = [] # First loop: determine which words are placed in each line for in_line in text.split('\n'): line = "" words = in_line.split(' ') for word in words: if not line == "": line += " " if (font.size(line + word)[0] > width): lines.append(line) line = word.replace('\n', '') else: line += word lines.append(line) # Second loop: render each line individually rendered_lines = [] total_height = 0 for line in lines: rendered_line = font.render(line, True, color, background) total_height += rendered_line.get_height() rendered_lines.append(rendered_line) # Third loop: bring everything together into one surface object final_surface = pygame.Surface((width, total_height)) y = 0 for rendered_line in rendered_lines: final_surface.blit(rendered_line, (0, y)) y += rendered_line.get_height() - 10 return final_surface
def display_infos(surf: pg.Surface, *args, font: pg.font = myFont, center: bool = False, x: int = None, y: int = None, textColor: pg.Color = pg.Color(255, 255, 255)): """ Affiche du texte à l'endroit indiqué avec des options de customisation :param surf: :param args: :param font: :param center: :param x: :param y: :param textColor: """ infos = "".join(args) textsurf = font.render(infos, True, textColor) if not center: surf.blit(textsurf, (x, y)) else: x = surf.get_width() // 2 - textsurf.get_width( ) // 2 if x is None else x y = surf.get_height() // 2 - textsurf.get_height( ) // 2 if y is None else y surf.blit(textsurf, (x, y))
def update(self, font: pygame.font) -> None: """ Updates ItemDropDisplay surface each frame :param font: Font in which the text should be written in :return: None """ self.fill(ITEM_DROP_DISPLAY_BACKGROUND) for pos, item in enumerate(self.__items): # Background rect with the rarity of the item as its colour pygame.draw.rect( self, DataLoader.rarities[DataLoader.possible_items[item[0]] ["rarity"]], pygame.Rect(self.width - item[1].get_width(), (pos * item[1].get_height()), item[1].get_width(), item[1].get_height())) # Dimensions which the text will take up str_width, str_height = font.size(item[0]) # Draw item image self.blit(item[1], (self.width - item[1].get_width(), (pos * item[1].get_height()))) # Draw item name text self.blit(font.render(item[0], True, TEXT_COLOUR), (self.width - item[1].get_width() - str_width, (pos * item[1].get_height()) + (str_height // 2)))
def update(self, font: pygame.font, player_mana: int) -> None: """ Updates mana bar surface :param font: Font to be used to render the text :param player_mana: The amount of mana the player has :return: None """ self.fill((0, 0, 0, 0)) # Amount of mana left health_txt = str(int( (player_mana / self.__max_mana) * self.__max_mana)) # Border for mana bar pygame.draw.rect( self, MANABAR_BACKGROUND_COLOUR, pygame.Rect( font.size(health_txt)[0], 0, self.__width - font.size(health_txt)[0], self.__height), 2) # Main bar that shows amount pygame.draw.rect( self, MANABAR_BACKGROUND_COLOUR, pygame.Rect( font.size(health_txt)[0], 0, (self.__width - font.size(health_txt)[0]) * (player_mana / self.__max_mana), self.__height)) self.blit(font.render(health_txt, True, MANABAR_TEXT_COLOUR), (0, self.__height // 4))
def update(self, font: pygame.font) -> None: """ Updates the XPBar surface :param font: Font to be used to render the text :return: None """ self.fill(XPBAR_BACKGROUND) # Get current XP and player level xp, lvl = DataLoader.player_data["xp"], DataLoader.player_data["level"] # XP needed per level = level * 100 xp_needed = lvl * 100 # Draw inner XP indicator pygame.draw.rect( self, XPBAR_BAR, pygame.Rect(0, 0, self.__width - (self.__width * (1 - (xp / xp_needed))), self.__height)) # Draw outer border pygame.draw.rect(self, XPBAR_BORDER, pygame.Rect(0, 0, self.__width, self.__height), 15) # Draw text displaying level and XP lvl_str = f"Level {lvl}: {xp}/{xp_needed}" self.blit(font.render(lvl_str, True, TEXT_COLOUR), ((self.__width // 2) - (font.size(lvl_str)[0] // 2), (self.__height // 2) - (font.size(lvl_str)[1] // 2)))
def update(self, font: pygame.font) -> None: """ Updates the Attributes surface :param font: Font to be used to render the text :return: None """ self.fill(ATTRIBURES_BACKGROUND) self.__attr_data = DataLoader.player_data["attributes"] # Draw outer border pygame.draw.rect(self, ATTRIBURES_BORDER, pygame.Rect(0, 0, self.__width, self.__height), 5) # Loop through attribute data for pos, key in enumerate(self.__attr_data): # Draw attr number box pygame.draw.rect( self, ATTRIBURES_BORDER, pygame.Rect(self.__width // 8, (self.__height // 5) * (pos + 1), self.__width // 2, self.__button_size * 2), 5) # Draw plus and minus images self.blit(self.__plus_img, self.__pluses[pos]) self.blit(self.__minus_img, self.__minuses[pos]) # Draw attr names and attr number text self.blit(font.render(key, True, TEXT_COLOUR), (((self.__width // 8) + (self.__width // 4)) - (font.size(key)[0] // 2), ((self.__height // 5) * (pos + 1)) - font.size(key)[1])) self.blit( font.render(str(self.__attr_data[key]), True, TEXT_COLOUR), (((self.__width // 8) + (self.__width // 4)) - (font.size(str(self.__attr_data[key]))[0] // 2), ((self.__height // 5) * (pos + 1)) + font.size(str(self.__attr_data[key]))[1])) # Draw remaining skill point indicator pygame.draw.rect( self, ATTRIBURES_SP_BORDER, pygame.Rect(self.__width // 5, self.__height - 30, (self.__width // 5) * 3, 25)) self.blit( font.render( f"Unused SP: {DataLoader.player_data['unused_sp']}", True, TEXT_COLOUR), (self.__width // 5, self.__height - 25))
def message(self, text: str, font: pg.font, color: Tuple[int, ...], center_pos: Tuple[int, int]): pg.font.init() # Creates text object text_render = font.render(text, True, color) text_rect = text_render.get_rect() text_rect.center = center_pos # Displays text onto screen self.screen.blit(text_render, text_rect)
def update(self, font: pygame.font, data: dict) -> None: """ Updates the Equipment surface :param font: Font to be used to render the text :param data: Dict containing the current item the mouse is over :return: None """ self.fill(EQUIPMENT_BACKGROUND) # Get current equipped armour imgs and names self.__imgs = self.__get_imgs() self.__armor_names = self.__get_armor_names() # Draw outer border pygame.draw.rect(self, EQUIPMENT_BORDER, pygame.Rect(0, 0, self.__width, self.__height), 5) # Create defense and coin strings defense = f"Defense: {str(sum([DataLoader.possible_items[i]['defense'] for i in self.__armor_names]))}" coins = f"Coins: {DataLoader.player_data['coins']}" # Draw the defense text self.blit(font.render(defense, True, TEXT_COLOUR), (5, self.__height - font.size(defense)[1])) # Draw the coins text self.blit(font.render(coins, True, COIN_TEXT_COLOUR), (self.__width - font.size(coins)[0] - 5, self.__height - font.size(defense)[1])) # Have to use pos like this as you cant enumerate the loop pos = 0 # Draw the armour slots for slot, img, armor in zip(self.__slots, self.__imgs, self.__armor_names): pygame.draw.rect( self, DataLoader.rarities[DataLoader.possible_items[armor] ["rarity"]], slot) self.blit(img, slot) if data is not None: if pos == data["eq_pos"]: pygame.draw.rect(self, EQUIPMENT_SELECTED, slot, 5) pos += 1
def car_network(screen: pygame.Surface, font: pygame.font, network: Network): """Affiche le réseau neuronal d'une voiture Chaque neurone sera représenté avec sa valeur, ainsi que les liaisons pondérées entre eux Parameters ---------- screen: La fenêtre du programme font: :mod:`pygame.font` La police utilisée network: Le réseau neuronal dont les informations seront extraites """ _, y = SETTINGS.screen_size x = ceil(25 * SETTINGS.scale_x) diam = 15 y -= ceil((20 + (diam + 10) * len(network.I_layer)) * SETTINGS.scale_y) diam = ceil(diam * SETTINGS.scale_avg) circle_color = SETTINGS.colors["neuron-color"] text_color = SETTINGS.colors["neuron-text-color"] circles = list() texts = list() neurons = list() y_space = ceil(20 * SETTINGS.scale_y) x_space = ceil(80 * SETTINGS.scale_x) for layer in [ network.I_layer, network.layer_2, network.layer_3, network.layer_4 ]: height = (diam + y_space) * len(layer) y2 = y + height / 2 temp = list() for n in layer: circles.append((screen, circle_color, (x, round(y2)), diam)) texts.append((font.render(str(round(n.value * 1000)), True, text_color, None), (x, y2))) temp.append((n, (x, y2))) y2 -= diam + y_space neurons.append(temp) x += diam + x_space for e in range(len(neurons) - 1): for n1 in neurons[e]: for e2, n2 in enumerate(neurons[e + 1]): n_weight = (n1[0].weight[e2] + 2) / 4 color = (round(n_weight * 200), ) * 3 w = ceil((round(n_weight * 3) + 1) * SETTINGS.scale_avg) pygame.draw.line(screen, color, n1[1], n2[1], w) for c in circles: pygame.draw.circle(*c) for text, coo in texts: rect = text.get_rect() screen.blit(text, (coo[0] - rect.width / 2, coo[1] - rect.height / 2))
def update(self, name: str, font: pygame.font, data: dict) -> None: """ Updates inspector surface each frame :param name: Name of the item being inspected :param font: Font used to write the text :param data: Dict containing data, e.g {'img': pygame.image, 'attr': {..., ...}} :return: None """ self.fill(INSPECTOR_BACKGROUND) if data is not None: if data["st_pos"] is not None: rarity_col = (0, 0, 0) else: rarity_col = DataLoader.rarities[data["attr"]["rarity"]] # Draw border of inspector with colour of item rarity pygame.draw.rect(self, rarity_col, pygame.Rect(0, 0, self.__width, self.__height), 5) # Draw background of image location pygame.draw.rect( self, rarity_col, pygame.Rect(self.__width // 2 - (data["img"].get_width() // 2), 10, data["img"].get_width(), data["img"].get_height())) # Draw name with underline font.set_underline(True) self.blit(font.render(name, True, TEXT_COLOUR), (self.__width // 2 - (font.size(name)[0] // 2), 90)) font.set_underline(False) # If there is data provided, loop through and draw it self.blit(data["img"], (self.__width // 2 - (data["img"].get_width() // 2), 10)) for pos, k in enumerate(data["attr"]): self.blit( font.render(f"{k}: {data['attr'][k]}", True, TEXT_COLOUR), (10, 110 + (20 * pos)))
def draw_point(point: Vector, color: Tuple[int, int, int], surf: pygame.Surface, radius: int, font: pygame.font, text: str, text_color: Tuple[int, int, int]) -> None: projected = Engine.get_projection([point])[0][:] if radius > 1: pygame.draw.circle(surf, color, (round(projected[0]), round(projected[1])), radius) else: surf.set_at((round(projected[0]), round(projected[1])), color) if text != '': surf.blit(font.render(str(text), True, text_color), (round(projected[0]), round(projected[1])))
def __init__(self, x: int, y: int, text: str, font: pygame.font = FONT_TITLE, fontAntialias: bool = True, fontColor: Tuple[int,int,int] = (0, 0, 0), fontBackground: Optional[Tuple[int,int,int]] = None, **kwargs ) -> None: """ UILabel constructor """ self.font = font self.text = text self.fontAntialias = fontAntialias self.fontColor = fontColor surface = font.render(text, fontAntialias, fontColor, fontBackground) super().__init__(x, y, *surface.get_size(), surface=surface, background=fontBackground, **kwargs)
def update(self, font: pygame.font, data: dict) -> None: """ Updates skill tree surface each frame :param font: Font to use to draw text :param data: Data to determine which rect was collided :return: None """ self.fill(SKILLTREE_BACKGROUND) # Get skill points text to be drawn text = f"Unused SP: {DataLoader.player_data['unused_sp']}" # Draw border of surface pygame.draw.rect(self, SKILLTREE_BORDER, pygame.Rect(0, 0, self.__width, self.__height), 5) # Draw skill point border pygame.draw.rect( self, SKILLTREE_SP_BORDER, pygame.Rect((self.__width // 2) - (font.size(text)[0] // 2), self.__height - font.size(text)[1], font.size(text)[0], font.size(text)[1])) # Draw skill point text self.blit(font.render(text, True, TEXT_COLOUR), ((self.__width // 2) - (font.size(text)[0] // 2), self.__height - font.size(text)[1])) # Draw connecting lines between each tree element for line in self.__lines: pygame.draw.aaline(self, (255, 255, 255), (line[0][0], line[0][1]), (line[1][0], line[1][1])) # Draw skill image for pos, rect in enumerate(self.__level_rects): # Draw border around image if the mouse is hovered over it if data is not None: if data["st_pos"] == rect: pygame.draw.rect(self, (255, 255, 255), rect, 5) self.blit( self.__imgs[pos] if self.__levels[pos]["elem"].tag in DataLoader.player_data["skills"] else self.__bw_imgs[pos], rect)
def center(screen_width: int, texts: list, font: pygame.font) -> list: """ Return list of tuple(surface,center_rect) screen_width:Width of the screen texts:text we wanted to center.Each item of text will be separted by new line font:pygame font we wanted to use """ center_texts = list() for i, text in enumerate(texts): line = font.render(text, True, WHITE) rect = line.get_rect() rect.center = ((screen.get_width() / 2), (150 + 30 * i)) screen.blit(line, rect) center_texts.append((line, rect)) return center_texts
def write_text(screen: pg.Surface, text: str, font: pg.font, color: Tuple, pos: Tuple) -> None: """Write the <text> on <screen> at <post> with <font> and <color>""" text_surface = font.render(text, 1, color) screen.blit(text_surface, pos)
def circle_label(screen, font: pygame.font, xy, label): node_label = font.render(label, True, white) screen.blit(node_label, (xy[0] - 10, xy[1] - 10))