Pygame- rotate sprite and follow path simultaneously

Question:

I’m trying to animate a ball getting thrown, and I want it to rotate an follow a smooth, parabolic path at the same time. However, I just can’t seem to get pygame.transform.rotate() to cooperate.

Here’s what I’ve tried so far:

import pygame
screen = pygame.display.set_mode((500, 500))
timer = pygame.time.Clock()
ball = pygame.sprite.Sprite()
ball.image = pygame.image.load("throwball.png")
ball.image = pygame.transform.scale(ball.image, (48,48))
ball.rect = ball.image.get_rect(topleft = (50,50))
ball.orig_image = ball.image
rotaterect = ball.rect

for i in range(60):
    #pygame.draw.rect(screen, Color(255,255,255), ball.rect)
    ball.image = pygame.transform.rotate(ball.orig_image, i*20)
    rotaterect.topleft = (5*i,((i-20)*(i-20) + 1)/5)
    ball.rect.center = rotaterect.center
    screen.blit(ball.image, ball.rect)
    pygame.display.update()
    timer.tick(60)
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
while 1:
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

Whenever I run the code, the ball moves in an irregular pattern. I made a second rect to try to keep the positioning under control, but the ball ends up forming a path like this: this

Obviously there’s something wrong with the positioning on each frame, but I’m not sure why any of the frames would be out of place, since their location is determined by their center point.

Here’s the ball image:

enter image description here

It’s 16×16 (square), so I’m dumbfounded as to why the image isn’t following a clean path.

Asked By: Alex Foster

||

Answers:

Note, a rotated image varies in size. See How do I rotate an image around its center using Pygame?.

Get the rectangle of the rotated image and set the center of the rectangle by the center of the helper rectangle rotaterect. This causes that the image is symmetrically aligned around the center.
You missed to update the ball.rect to the actual size of the rotated image:

ball.rect = ball.image.get_rect()
rotaterect.topleft = (5*i,((i-20)*(i-20) + 1)/5)
ball.rect.center = rotaterect.center

Example:

for i in range(60):
    ball.image = pygame.transform.rotate(ball.orig_image, i*20)
    ball.rect = ball.image.get_rect()
    rotaterect.topleft = (5*i,((i-20)*(i-20) + 1)/5)
    ball.rect.center = rotaterect.center
    screen.blit(ball.image, ball.rect)
    pygame.display.update()
Answered By: Rabbid76
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.