Why does my PyGame rotation look so goofy?

Issue

I am trying to rotate an image in PyGame, and I don’t know how to describe it, but it’s very goofy. Here’s my code.

import sys, pygame
pygame.init()

size = width, height = 600, 600
green = 50, 168, 82

screen = pygame.display.set_mode(size)


class Capybara:
    def __init__(self, size_multiplier):
        self.capybara = pygame.image.load('capybara.gif')
        self.x = 300
        self.y = 300
        self.o_size = 92, 206
        self.new_size = (self.o_size[0] * size_multiplier,self.o_size[1] * size_multiplier)
        self.capybara = pygame.transform.scale(self.capybara, self.new_size)
        self.base_capybara = self.capybara
        self.rotation = 0

    def rotate(self, amount):
        self.rotation += amount
        if self.rotation == 361:
            self.rotation = 0
        elif self.rotation == -1:
            self.rotation = 360
        print(self.rotation)
        self.capybara = pygame.transform.rotate(self.base_capybara, self.rotation)

capybara = Capybara(0.8)

fpsClock = pygame.time.Clock()

rotate_l = False
rotate_r = False

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()

            quit()

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                rotate_l = True
                if rotate_r:
                    rotate_r = False
            if event.key == pygame.K_RIGHT:
                rotate_r = True
                if rotate_l:
                    rotate_l = False

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                rotate_l = False
            if event.key == pygame.K_RIGHT:
                rotate_r = False

    if rotate_l:
        capybara.rotate(-1)
    if rotate_r:
        capybara.rotate(1)

    screen.fill(green)
    screen.blit(capybara.capybara, (capybara.x - int(capybara.new_size[0]/2), capybara.y - int(capybara.new_size[1]/2)))
    pygame.display.update()
    fpsClock.tick(60)

And here’s what I mean by goofy: https://gyazo.com/4dd3a679d963595849e0412307b95fa9
Here’s the capybara image too, if you want to test.

capybara

Solution

It looks so "goofy, because you do not rotate around the center of the image. See How do I rotate an image around its center using PyGame?.
The size of the image changes when the image is rotated. Create a rectangule size of the image and set the center point of the rectangle. Update the rectangle when the image rotates and use the rectangle to blint the image:

import sys, pygame
pygame.init()

size = width, height = 600, 600
green = 50, 168, 82

screen = pygame.display.set_mode(size)

class Capybara:
    def __init__(self, size_multiplier):
        self.capybara = pygame.image.load('capybara.gif')
        self.o_size = 92, 206
        self.new_size = (self.o_size[0] * size_multiplier,self.o_size[1] * size_multiplier)
        self.capybara = pygame.transform.scale(self.capybara, self.new_size)
        self.base_capybara = self.capybara
        self.rotation = 0
        self.rect = self.capybara.get_rect(center = (300, 300))

    def rotate(self, amount):
        self.rotation += amount
        if self.rotation == 361:
            self.rotation = 0
        elif self.rotation == -1:
            self.rotation = 360
        print(self.rotation)
        self.capybara = pygame.transform.rotate(self.base_capybara, self.rotation)
        self.rect = self.capybara.get_rect(center = self.rect.center)

capybara = Capybara(0.8)

fpsClock = pygame.time.Clock()

rotate_l = False
rotate_r = False

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                rotate_l = True
                if rotate_r:
                    rotate_r = False
            if event.key == pygame.K_RIGHT:
                rotate_r = True
                if rotate_l:
                    rotate_l = False

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                rotate_l = False
            if event.key == pygame.K_RIGHT:
                rotate_r = False

    if rotate_l:
        capybara.rotate(-1)
    if rotate_r:
        capybara.rotate(1)

    screen.fill(green)
    screen.blit(capybara.capybara, capybara.rect)
    pygame.display.update()
    fpsClock.tick(60)

Answered By – Rabbid76

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published