I had been trying to rotate an image around its center in using pygame.transform.rotate() but it\'s not working. Specifically the part that hangs is rot_i
There are some problems with the top answer: The position of the previous rect needs to be available in the function, so that we can assign it to the new rect, e.g.:
rect = new_image.get_rect(center=rect.center)
In the other answer the location is obtained by creating a new rect from the original image, but that means it will be positioned at the default (0, 0) coordinates.
The example below should work correctly. The new rect needs the center position of the old rect, so we pass it as well to the function. Then rotate the image, call get_rect to get a new rect with the correct size and pass the center attribute of the old rect as the center argument. Finally, return both the rotated image and the new rect as a tuple and unpack it in the main loop.
import pygame as pg
def rotate(image, rect, angle):
"""Rotate the image while keeping its center."""
# Rotate the original image without modifying it.
new_image = pg.transform.rotate(image, angle)
# Get a new rect with the center of the old rect.
rect = new_image.get_rect(center=rect.center)
return new_image, rect
def main():
clock = pg.time.Clock()
screen = pg.display.set_mode((640, 480))
gray = pg.Color('gray15')
blue = pg.Color('dodgerblue2')
image = pg.Surface((320, 200), pg.SRCALPHA)
pg.draw.polygon(image, blue, ((0, 0), (320, 100), (0, 200)))
# Keep a reference to the original to preserve the image quality.
orig_image = image
rect = image.get_rect(center=(320, 240))
angle = 0
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
angle += 2
image, rect = rotate(orig_image, rect, angle)
screen.fill(gray)
screen.blit(image, rect)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
Here's another example with a rotating pygame sprite.
import pygame as pg
class Entity(pg.sprite.Sprite):
def __init__(self, pos):
super().__init__()
self.image = pg.Surface((122, 70), pg.SRCALPHA)
pg.draw.polygon(self.image, pg.Color('dodgerblue1'),
((1, 0), (120, 35), (1, 70)))
# A reference to the original image to preserve the quality.
self.orig_image = self.image
self.rect = self.image.get_rect(center=pos)
self.angle = 0
def update(self):
self.angle += 2
self.rotate()
def rotate(self):
"""Rotate the image of the sprite around its center."""
# `rotozoom` usually looks nicer than `rotate`. Pygame's rotation
# functions return new images and don't modify the originals.
self.image = pg.transform.rotozoom(self.orig_image, self.angle, 1)
# Create a new rect with the center of the old rect.
self.rect = self.image.get_rect(center=self.rect.center)
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
all_sprites = pg.sprite.Group(Entity((320, 240)))
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
return
all_sprites.update()
screen.fill((30, 30, 30))
all_sprites.draw(screen)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()