How do I rotate an image around its center using Pygame?

后端 未结 6 1529
[愿得一人]
[愿得一人] 2020-11-22 00:13

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

6条回答
  •  南旧
    南旧 (楼主)
    2020-11-22 01:10

    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()
    

提交回复
热议问题