def drawRect(cls, pos: Vect2d, size: Vect2d, color: Color, base_pos: Vect2d = Vect2d(0, 0), fill: bool = True) -> None: """Procédure pour dessiner un rectangle à l'écran Args: pos (Vect2d): position du coin en haut à gauche rectangle size (Vect2d): taille du rectangle color (Color): couleur RGBA base_pos (Vect2d): position de référence de la fenêtre fill (bool): rectangle rempli ou non """ size = size.copy() pos = pos.copy() if base_pos.length() != 0: pos = (pos - base_pos) * cls.zoom_factor pos = pos.toIntValues() if base_pos.length() != 0: size *= cls.zoom_factor size = size.toIntValues() rect = pygame.Rect(pos.toTuple(), size.toTuple()) if fill: pygame.gfxdraw.box(cls.window, rect, color) else: pygame.gfxdraw.rectangle(cls.window, rect, color)
def speedEnemies(self, map_size: Vect2d) -> tuple: dist_target = float("inf") dist_hunter = float("inf") speed_target = None speed_hunter = None can_split = False score_target = None for enemy_pos, enemy_radius, enemy_score in self.creatures_info: dist = Vect2d.dist(self.pos, enemy_pos) - self.radius - enemy_radius if Creature.canEat(enemy_score, self.score): if dist < dist_hunter: speed_hunter = enemy_pos - self.pos dist_hunter = dist elif Creature.canEat(self.score, enemy_score): if dist < dist_target: speed_target = enemy_pos - self.pos dist_target = dist score_target = enemy_score if score_target is not None: if score_target < self.score // 2: if dist_target > self.radius and dist_target < self.radius * 2: can_split = True if speed_hunter is None: speed_hunter = Vect2d(0, 0) if speed_target is None: speed_target = Vect2d(0, 0) coeff_target = 1 - dist_target / map_size.length() coeff_target = abs(coeff_target**3) if coeff_target == float("inf"): coeff_target = 0 elif coeff_target >= 1: coeff_target = 1 coeff_target = coeff_target if coeff_target != float("inf") else 0 coeff_hunter = 1 - dist_hunter / map_size.length() coeff_hunter = abs(coeff_hunter**3) if coeff_hunter == float("inf"): coeff_hunter = 0 elif coeff_hunter >= 1: coeff_hunter = 1 return speed_target, coeff_target, speed_hunter, coeff_hunter, can_split
def drawImg(cls, img: pygame.Surface, pos: Vect2d, base_pos: Vect2d = Vect2d(0, 0), radius: int = None) -> None: """Procédure pour dessiner une image circulaire à l'écran Args: img (pygame.Surface): image à dessiner pos (Vect2d): position de l'image base_pos (Vect2d): position de référence de la fenêtre radius (int): rayon désiré de l'image """ pos = pos.copy() if base_pos.length() != 0: pos = (pos - base_pos) * cls.zoom_factor pos = pos.toIntValues() radius = int(radius * cls.zoom_factor) if radius is not None: pos -= Vect2d(radius, radius) img = pygame.transform.smoothscale(img, (radius * 2, radius * 2)) # On agrandit (ou réduit) la taille de l'image cls.window.blit(img, pos.toTuple())
def drawLine(cls, pos1: Vect2d, pos2: Vect2d, color: Color, base_pos: Vect2d = Vect2d(0, 0), width: int = 1) -> None: """Procédure pour dessiner une ligne à l'écran Args: pos1 (Vect2d): position de départ pos2 (Vect2d): position d'arrivée color (Color): couleur de la ligne base_pos (Vect2d): position de référence de la fenêtre width (int): largeur de la ligne """ pos1 = pos1.copy() pos2 = pos2.copy() if base_pos.length() != 0: pos1 = (pos1 - base_pos) * cls.zoom_factor pos2 = (pos2 - base_pos) * cls.zoom_factor pos1 = pos1.toIntValues() pos2 = pos2.toIntValues() if width == 1: pygame.gfxdraw.line(cls.window, pos1.x, pos1.y, pos2.x, pos2.y, color) else: pygame.draw.line(cls.window, color, pos1.toTuple(), pos2.toTuple(), width)
def drawCircle(cls, pos: Vect2d, color: Color, radius: int, base_pos: Vect2d = Vect2d(0, 0), fill: bool = True) -> None: """Procédure pour dessiner un cercle à l'écran Args: pos (Vect2d): position du centre du cercle color (Color): couleur RGBA radius (int): rayon du cercle base_pos (Vect2d): position de référence de la fenêtre fill (bool): cercle rempli ou non """ pos = pos.copy() if base_pos.length() != 0: pos = (pos - base_pos) * cls.zoom_factor pos = pos.toIntValues() radius = int(radius * cls.zoom_factor) if pos.x in range(-radius, cls.size.x + radius) and pos.y in range( -radius, cls.size.y + radius): if fill: pygame.gfxdraw.filled_circle(cls.window, pos.x, pos.y, radius, color) # Dessine un cercle plein pygame.gfxdraw.aacircle(cls.window, pos.x, pos.y, radius, color)
def drawTriangle(cls, pos: Vect2d, color: Color, radius: int, angle: float, base_pos: Vect2d = Vect2d(0, 0), fill: bool = True) -> None: """Procédure pour dessiner un triangle à l'écran Args: pos (Vect2d): position du centre du rectangle color (Color): couleur RGBA radius (int): distance du centre aux sommets base_pos (Vect2d): position de référence de la fenêtre fill (bool): triangle rempli ou non """ pos = pos.copy() if base_pos.length() != 0: pos = (pos - base_pos) * cls.zoom_factor pos = pos.toIntValues() nodes = [] # Sommets du triangle for i in range(3): local_angle = 2 * i * math.pi / 3 + angle nodes.append( int(pos.x + math.cos(local_angle) * radius * cls.zoom_factor)) nodes.append( int(pos.y + math.sin(local_angle) * radius * cls.zoom_factor)) if fill: pygame.gfxdraw.filled_trigon(cls.window, *nodes, color) # Triangle plein pygame.gfxdraw.aatrigon(cls.window, *nodes, color)
def drawText( cls, text: str, pos: Vect2d, size: int = 16, color: Color = Color.WHITE, base_pos: Vect2d = Vect2d(0, 0)) -> None: """Procédure pour afficher du texte à l'écran On essaie de garder en mémoire les polices chargées pour éviter de recharger la police à chaque frame Args: text (str): texte à afficher pos (Vect2d): position du texte size (int): taille de la police utilisée color (Color): couleur du texte, blanc par défaut base_pos (Vect2d): position de référence de la fenêtre """ pos = pos.copy() if base_pos.length() != 0: pos = (pos - base_pos) * cls.zoom_factor pos = pos.toIntValues() if base_pos.length() != 0: size *= cls.zoom_factor font_size = round(size) if not (pos.x in range(-font_size * len(text), cls.size.x + font_size * len(text)) and pos.y in range(-font_size, cls.size.y + font_size)): return font_family = "comicsansms" if cls.all_font.get(font_family, None) is None: # Si la police n'existe pas encore cls.all_font[font_family] = {} if cls.all_font[font_family].get(size, None) is None: # Si la taille de la police n'existe pas encore cls.all_font[font_family][font_size] = pygame.font.SysFont( font_family, font_size) # On charge la police font = cls.all_font[font_family][font_size] # On utilise la police text = str(text) color = [ int(color[i]) if color[i] <= 255 else 255 for i in range(len(color)) ] # On veut une couleur avec des nombres entiers text_surface = font.render(text, True, color) if len(color) == 4 and color[3] != 255: # Si la couleur a de la transparence alpha_img = pygame.Surface(text_surface.get_size(), pygame.SRCALPHA) alpha_img.fill((255, 255, 255, color[3])) text_surface.blit(alpha_img, (0, 0), special_flags=pygame.BLEND_RGBA_MULT) size = Vect2d(text_surface.get_width(), text_surface.get_height()) pos -= size // 2 cls.window.blit(text_surface, pos.toTuple())