Rotating a sprite using pygame

najanaja73

Newbie
Joined
Nov 18, 2014
Messages
4
Hi, I've just started using Python/Pygame as a hobby. I've gotten the code to draw my Plane.png and move it using the wsad keys, and I mapped the q and e keys to rotate it which it does, but each time it rotates, it 'falls' down the screen to the bottom right and after a few key presses, disappears. I read that this is because when it turns the sprite, it adds padding to resize the image while it is turning. I think that each time it turns, it adds more padding, making it add exponentially for each keypress. I can't figure out how to stop this from happening. Any help for a beginner greatly appreciated! The Colours import is just a file where I keep my pre-defined colours for easier colour filling, and Plane.gif is an inch by inch and a half gif of a black plane with transparent background, and loads no problem, it just flies away when i use the e or q keys

Code:
import pygame, sys, time, random
from pygame.locals import *
from Colours import *
from PIL import Image, ImageDraw
 
 
class MySprite(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('Plane.gif').convert()
        self.rect = self.image.get_rect()
        self.x = 0
        self.y = 0
 
    def draw(self,surface):
 
            surface.blit(self.image,(self.x,self.y))
 
 
    def onKeyPress(self):
 
        key = pygame.key.get_pressed()
        distance = 5
        if key[ord('s')] or key[pygame.K_DOWN]: #down
            self.y += distance
        elif key[ord('w')] or key[pygame.K_UP]: #up
            self.y -= distance
        if key[ord('d')] or key[pygame.K_RIGHT]: #right
            self.x += distance
        elif key[ord('a')] or key[pygame.K_LEFT]: #left
            self.x -= distance
 
        rotate = pygame.transform.rotate
        if key[ord('e')]:
            self.image = rotate(self.image, 10)
        elif key[ord('q')]:
            self.image = rotate(self.image, -10)
 
class Event(object):
 
    def __init__(self):
 
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
 
 
pygame.init()
 
fps = 30
fpsClock = pygame.time.Clock()
 
size = width,height = 800,600
screen = pygame.display.set_mode(size)
mySprite = MySprite()
 
while True:
 
    event = Event()
    screen.fill(Blue)
 
    mySprite.draw(screen)
    mySprite.onKeyPress()
 
    pygame.display.update()
 
    fpsClock.tick(fps)
 
This is the code, hope you can help, thanks!
 
Last edited by a moderator:

sebt3

homebrew player (P. & C.)
Joined
Sep 9, 2008
Messages
4,747
Age
39
Location
France
Website
sebt3.openpandora.org
This forum is only related to the pandora (see www.openpandora.org). But you might get a reply anyway as some of us are snake friendly...

But please edit your post so your code is actually readable use the [ code ] tags for doing it.
 

najanaja73

Newbie
Joined
Nov 18, 2014
Messages
4
@seb3 yes, I wasn't aware of the

Code:
 tag, but I've made it more readable.
Glad you are snake friendly! hope someone replies(even though it must be a simple question), because everything I try doesn't fix it.
 

levi

Still fresh, damnit!
Joined
Oct 6, 2008
Messages
11,371
Location
Somewhere off the coast of the EU
I can't see anything immediately in your code that would add the padding, so I assume it happens automatically in the rotate() function. To fix that, I'd suggest you maintain a copy of your original unrotated image, and store the number of degrees to rotate it. Then when you press the rotation keys, add or subtract 10 from the number of degrees and regenerate your self.image from the original image rotated that amount. It will probably still bobble up and down as you rotate it, so to fix that I'd suggest you base your coordinates around the middle of the sprite rather than its corner, and regenerate self.rect every time you rotate it, so you can compute the corner coordinates for when you need to render it. But do the first thing first and test that, because I've not used pygame and could well be wrong in my diagnosis.
 

najanaja73

Newbie
Joined
Nov 18, 2014
Messages
4
Thank Levi.

Yes, that looks like something I can work on. No idea how to do it yet, but I'll eventually figure it out! I tried subtracting the rect.x and y positions every time but didn't refresh it every time. And I also didn't store degrees of the copy, but I'll try that, thanks.
 

drock

Member
Joined
Sep 5, 2010
Messages
131
Ya I think you are right on Levi after taking a look at the pygame docs.  There is someone mentioning exactly what you said about storing an original copy and just keeping track of degrees and basing the location off the center of the image.

@Najanaja73 when you say you tried subtracting the rect.x and y positions are you talking about trying to keep the image at the correct height?  If you are you are what I believe Levi meant to find the half way point of each side (rect.x/2,rect.y/2) and use that to keep the image stable.  This way you are always using the center of the image to put it on the screen.
 
Top