Pygame, rotate image without having to load the image in every iteration

Viewed 153

So im writing a simple game in python, im blitting an image, i create an object once and in each iteration of loop, i update x and y of that object, it works file as long as there is no rotation needed. When rotation is needed, the image disappears, so i load the image again when it comes to rotation. As im loading the image again, my game lags a lot. Here is my code of that Sprite class

class PlayerSegment(pygame.sprite.Sprite):

def __init__(self, x, y, img, angle1=0, rotate=False, wid=80, hie=80, tl=False, cvt=False):
    super().__init__()
    self.x = x
    self.y = y
    self.img = img
    self.rotate, self.angle1 = rotate, angle1
    self.wid, self.hie, self.tl, self. cvt = wid, hie, tl, cvt
    self.image = pygame.image.load(self.img).convert_alpha()
    self.image = pygame.transform.scale(self.image, (self.wid, self.hie))
    if self.rotate:
        self.image = pygame.transform.rotate(self.image, self.angle1)
    self.rect = self.image.get_rect()
    if self.tl:
        self.rect.topleft = [self.x, self.y]
    else:
        self.rect.center = [self.x, self.y]
    self.width = self.image.get_width
    self.height = self.image.get_height

def get_image(self):
    if self.rotate:
        self.image = pygame.image.load(self.img)
        self.image = pygame.transform.scale(self.image, (self.wid, self.hie))
        self.image = pygame.transform.rotate(self.image, self.angle1)

    self.image.set_colorkey(WHITE)
    self.image.set_colorkey(BLACK)
    self.rect = self.image.get_rect()
    if self.tl:
        self.rect.topleft = [self.x, self.y]
    else:
        self.rect.center = [self.x, self.y]
    self.width = self.image.get_width()
    self.height = self.image.get_height()

im using this calss as below. Below code goes inside a loop

player_loader = SegmentClass.PlayerSegment(player_x, player_y, GameArt.spaceship[sprite_no], tl=False,
                                  angle1=angle, rotate=True, wid=70, hie=70)
player_loader.get_image()
display_surface.blit(player_loader.image, player_loader.rect)
player_loader.x, player_loader.y = player_x, player_y
player_loader.angle1 = angle

im updating angle and player_x, player_y somewhere else. CHeck Sprite class, i want to update x and y of the object without having to load the image again. Im acheiving it as long as im not using Rotate function. How can i rotate the image without have to load the image again and again? In simple words, i want to remove

self.image = pygame.image.load(self.img)

in method get_image()

2 Answers

if you use the same variable

 self.image = rotation(self.image) 

then you remove original image from memory

You should keep original image in other variable

self.image_original = pygame.image.load(self.img)

and use

self.image = self.image_original

or rotate it

self.image = rotate(self.image_original) 

BTW: If you always use the same scale then you could keep rescaled image

self.image_original = pygame.image.load(self.img)
self.image_scaled = scale(self.image_original)

and use

self.image = self.image_scaled

or rotate it

self.image = rotate(self.image_scaled) 

BTW: You can also keep rotated images in dictionary

self.image_rotated[90] = rotate(self.image_scaled, 90) 

and later only check

if angle not in self.image_rotated:
      self.image_rotated[angle] = rotate(self.image_scaled, angle) 

self.image = self.image_rotated[angle]

When you rotate you get a copy of the image back, blit that copy then you can rotate the original again without loading it from disk.

Related