PyGameExamplesAndAnswers

StackOverflow            reply.it reply.it

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” Martin Fowler (1999)


Rotate towards target or mouse

Related Stack Overflow questions:

You have to compute the angle of the vector from the player to the mouse. get the mouse position by pygame.mouse.get_pos() and the rectangle (pygame.Rect) around the player:

mx, my = pygame.mouse.get_pos()
player_rect = Player_1.get_rect(topleft=(P_X,P_Y))

Calculate the vector from the player to the mouse and compute the angle of vector by math.atan2. The y-axis needs to be reversed (-dy) as the y-axis is generally pointing up, but in the PyGame coordinate system the y-axis is pointing down.

dx, dy = mx - player_rect.centerx, player_rect.centery - my
angle = math.degrees(math.atan2(-dy, dx)) - correction_angle

In addition, a correction angle must be deducted (- correction_angle). The correction angle depends on the Sprite. If the Sprite

left is looking to the right, the correction angle is 0: correction_angle = 0
left is looking up, the correction angle is 90: correction_angle = 90
left is looking to the left, the correction angle is 180: correction_angle = 180
left is looking down, the correction angle is 90: correction_angle = 270

Rotate the player with pygame.transform.rotate() by the angle around its center:
(See also How do I rotate an image around its center using Pygame?)

rot_image = pygame.transform.rotate(Player_1, angle)
rot_image_rect = rot_image.get_rect(center=player_rect.center)

How do I make my player rotate towards mouse position?

📁 Minimal example - Rotate surface towards mouse

In pygame 2 dimensional vector arithmetic is implemented in pygame.math.Vector2.

Define a Vector2 object for the mouse position and the center of the triangle. Calculate the angle of vector form the center point to the mouse position (.angle_to()):

vMouse  = pygame.math.Vector2(mouse_pos)
vCenter = pygame.math.Vector2(center)
angle   = pygame.math.Vector2().angle_to(vMouse - vCenter)

Define the 3 points of the triangle around the (0, 0) and rotate them by the angle (.rotate())

points = [(-0.5, -0.866), (-0.5, 0.866), (2.0, 0.0)]
rotated_point = [pygame.math.Vector2(p).rotate(angle) for p in points]

To calculate the final points, the points have to b scaled and translated by the center of the triangle:

triangle_points = [(vCenter + p*scale) for p in rotated_point]

A version of the algorithm, without the use of pygame.math.Vector2, looks as follows:

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)
    len = math.hypot(dx, dy)
    if len > 0:
        dx, dy = (dx*scale/len, dy*scale/len) if len > 0 else (1, 0)

    pts = [(-0.5, -0.866), (-0.5, 0.866), (2.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

Note this version is probably faster. It needs a math.sqrt (or math.hypot) operation, in compare to math.atan2 which is probably used by .angle_to() and math.sin respectively math.cos which is probably used by .rotate(), of the former algorithm. The result coordinates are the same.

📁 Minimal example - Rotate triangle towards mouse

How to rotate a triangle to a certain angle in PyGame?

📁 Minimal example - Slowly rotate triangle towards mouse

player turns in wrong direction if angle is negative