math.atan2(y, x)
returns an angle in range -pi, pi. Probably the issue is cause by the transition form pi to -pi.
You know the vector from the center to the mouse
def mouse_direction():
x, y = width/2, height/2
mousex, mousey = pygame.mouse.get_pos()
dx, dy = mousex - x, mousey - y
return dx, dy
And you know the current direction of the player:
player_dir = math.cos(math.radians(player_angle)), math.sin(math.radians(player_angle))
Compute the normal (Perpendicular) direction to the current target direction
direction = mouse_direction()
normal_dir = -direction[1], direction[0]
And compute the Dot product between the current direction and the normal to the target direction:
dot_p_n = player_dir[0]*normal_dir[0] + player_dir[1]*normal_dir[1]
Since the dot product is proportional to the cosine of the angle between the 2 vectors, the angle can be changed dependent of the sign of dot_p_n
:
player_angle += -1 if dot_p_n > 0 else 1
See the example:

import pygame
import math
def rotate_triangle(center, scale, mouse_pos):
dx = mouse_pos[0] - center[0]
dy = mouse_pos[1] - center[1]
len = math.sqrt(dx*dx + dy*dy)
dx, dy = (dx*scale/len, dy*scale/len) if len > 0 else (1, 0)
pts = [(-0.5, -0.866), (-0.5, 0.866), (4.0, 0.0)]
pts = [(center[0] + p[0]*dx + p[1]*dy, center[1] + p[0]*dy - p[1]*dx) for p in pts]
return pts
disp = pygame.display.set_mode((200,200))
width, height = disp.get_size()
clock = pygame.time.Clock()
def mouse_direction():
x, y = width/2, height/2
mousex, mousey = pygame.mouse.get_pos()
dx, dy = mousex - x, mousey - y
return dx, dy
player_angle = 0
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
player_dir = math.cos(math.radians(player_angle)), math.sin(math.radians(player_angle))
direction = mouse_direction()
normal_dir = -direction[1], direction[0]
dot_p_n = player_dir[0]*normal_dir[0] + player_dir[1]*normal_dir[1]
player_angle += -1 if dot_p_n > 0 else 1
target_pos = width/2 + math.cos(math.radians(player_angle)), height/2 + math.sin(math.radians(player_angle))
points = rotate_triangle((100, 100), 10, target_pos)
pygame.Surface.fill(disp, (255,255,255))
pygame.draw.polygon(disp, (0,0,0), points)
pygame.display.update()