class Player(Entity): """Entity for the player, controls all movement and shooting""" def __init__(self, pos=SCREEN_CENTER): Entity.__init__(self, (18, 18), pos) # Acceleration vector that will be rotated and added to velocity self.acceleration = Vector(0, -0.2) # controls how quickly the ship slows down self.slow_speed = 0.1 # controls how quickly the ship rotates and slows its rotation self.rotate_increment = 0.5 self.slow_rotation = self.rotate_increment / 2 # 10 frame cooldown, start at 0 self.fire_cooldown = 0 # Group of all lasers for collision purposes self.lasers = SpriteGroup() # Draws an arrow facing in the direction of angle to serve as the ship size = self.image.get_size() arrow_points = [ (0, size[1] - 1), # bottom left ((size[0] - 1) / 2, 0), # top middle (size[0] - 1, size[1] - 1) # bottom right ] draw_lines(self.image, COLOR.WHITE, False, arrow_points, 2) def fire(self): """Fires a Laser Entity in the direction the ship is facing""" if self.fire_cooldown: self.fire_cooldown -= 1 else: self.lasers.add(Laser(self.position, self.angle)) self.fire_cooldown = 10 def kill(self): self.lasers.empty() Entity.kill(self) def calc_rotation(self): """Calculates the next angle in the rotation""" # Slow the rotation if self.rotation_speed > 0: self.rotation_speed -= self.slow_rotation elif self.rotation_speed < 0: self.rotation_speed += self.slow_rotation return Entity.calc_rotation(self) def calc_position(self): # simulate friction to slow the ship friction = self.velocity.length() - self.slow_speed if friction <= 0: friction = 0 try: self.velocity.scale_to_length(friction) except ValueError: # Fixes vector scaling issues self.velocity = Vector() return Entity.calc_position(self) def rotate(self, angle=0): self.acceleration.rotate_ip(self.rotation_speed) Entity.rotate(self, angle) def update(self): keys = get_pressed() if keys[K_LEFT]: self.rotation_speed -= self.rotate_increment if keys[K_RIGHT]: self.rotation_speed += self.rotate_increment if keys[K_UP]: self.velocity += self.acceleration if keys[K_z]: self.fire() Entity.update(self)
def add_width(pathway: typing.List[tuple], colors: typing.Dict[str, pygame.Color], screen_size: typing.Tuple[int]) -> dict: """Elargit le circuit à partir du tracé de base Pour chaque segment du tracé, on calcule la médiatrice du segment puis on trouve deux points sur cette médiatrice dont la distance respecte les constantes posées. Un nettoyage est ensuite réalisé pour supprimer les angles trop bruts ou inutiles, par la fonction :func:`check_angles`. Parameters ---------- pathway: Liste des points du tracé de base colors: Dictionnaire des couleurs à utiliser screen_size: (:class:`int`, :class:`int`) Taille en X,Y de la fenêtre Returns ------- :class:`dict`: Dictionnaire contenant le premier point supérieur ('point1'), le premier point inférieur ('point2') et toutes les :class:`classes.Border` du circuit ('bordures') """ points_over = list() points_under = list() result = list() delta = -round(MIN_PATH_WIDTH / 12), round(MIN_PATH_WIDTH / 12) new_delta = min(MIN_PATH_WIDTH + random.randrange(*delta), MAX_PATH_WIDTH) # First point vect = Vector(pathway[1][0] - pathway[0][0], pathway[1][1] - pathway[0][1]) vect.rotate_ip(90) vect.scale_to_length(new_delta) points_over.append( (pathway[0][0] - vect.x / 2, pathway[0][1] - vect.y / 2)) points_under.append( (pathway[0][0] + vect.x / 2, pathway[0][1] + vect.y / 2)) # Other points for enum in range(1, len(pathway) - 1): point1, point2, point3 = pathway[enum - 1], pathway[enum], pathway[enum + 1] vect = Vector(point2[0]-point1[0], point2[1]-point1[1]) \ + Vector(point3[0]-point2[0], point3[1]-point2[1]) vect.rotate_ip(90) new_delta = max( min(new_delta + random.randrange(*delta), MAX_PATH_WIDTH), MIN_PATH_WIDTH) vect.scale_to_length(new_delta) # points_over.append(point2) points_over.append((point2[0] - vect.x / 2, point2[1] - vect.y / 2)) points_under.append((point2[0] + vect.x / 2, point2[1] + vect.y / 2)) # Last point vect = Vector(pathway[-1][0] - pathway[-2][0], pathway[-1][1] - pathway[-2][1]) vect.rotate_ip(90) vect.scale_to_length(new_delta) points_over.append( (pathway[-1][0] - vect.x / 2, pathway[-1][1] - vect.y / 2)) points_under.append( (pathway[-1][0] + vect.x / 2, pathway[-1][1] + vect.y / 2)) # Cleanup of points check_angles(points_over) check_angles(points_under) for path in (points_over, points_under): for index in range(len(path) - 1): if colors is None: # debug only - couleur aléatoire color = ((index * 100 + 70) % 255, (index * 90 + 20) % 255, (index * 50 + 40) % 255) else: color = colors["borders"] if path[index][1] > screen_size[1] - 10: path[index][1] = screen_size[1] - 10 elif path[index][1] < 10: path[index][1] = 10 result.append(Border(path[index], path[index + 1], color)) black = (10, 10, 10) result.append( Border(points_over[0], points_under[0], colors["border-begin"] if colors is not None else black)) result.append( Border(points_over[-1], points_under[-1], colors["border-end"] if colors is not None else black)) return { "bordures": result, "point1": points_under[0], "point2": points_over[0] }