Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how should I rotate an image continuously using pygame?

Tags:

python

pygame

I have an image which I want to rotate continuously.

I thought of rotating it through a certain angle after specific interval of time . However, I wanted to implement a feature of shooting a bullet in the direction my head of the image is pointing at that moment of time when I click a specific key.

So at that moment of time , how should I keep the track of my head in the rotating image?

like image 240
Talha Chafekar Avatar asked Aug 29 '19 06:08

Talha Chafekar


1 Answers

Creating rotated images is computationally expensive. It is something that should be done once before your program enters its main loop.

A "continuously rotating" image is really a set of animation frames, each one advanced by some degree from the previous.

The pygame function pygame.transform.rotate() will rotate an image. It might be useful in your case to decide some step-angle, then make N images.

For example, if you desired 12 frames of rotation animation, create 11 more frames of animation each rotated by 360 / 12 degrees (is this off-by-one?).

This gives us a simple sprite class, which pre-creates the frames at the time of instantiation. Obviously if you had lots of sprites, it does not make sense to re-compute the same frames for each of them, but it serves as an example.

class RotatingSprite( pygame.sprite.Sprite ):

    def __init__( self, bitmap, rot_count=12 ):
        pygame.sprite.Sprite.__init__( self )
        self.rect        = bitmap.get_rect()
        self.rect.center = ( random.randrange( 0, WINDOW_WIDTH ), random.randrange( 0, WINDOW_HEIGHT ) )
        # start with zero rotation
        self.rotation    = 0
        self.rotations   = [ bitmap ]
        self.angle_step  = rot_count
        self.angle_slots = 360 // self.angle_step
        # pre-compute all the rotated images, and bitmap collision masks
        for i in range( 1, self.angle_slots ):
            rotated_image = pygame.transform.rotate( bitmap, self.ANGLE_STEP * i )
            self.rotations.append( rotated_image )
        self._setRotationImage( 0 ) # sets initial image & rect

    def rotateRight( self ):
        if ( self.rotation == 0 ):
            self._setRotationImage( self.angle_slots - 1 )
        else:
            self._setRotationImage( self.rotation - 1 )

    def rotateLeft( self ):
        if ( self.rotation == self.angle_slots - 1 ):
            self._setRotationImage( 0 )
        else:
            self._setRotationImage( self.rotation + 1 )

    def _setRotationImage( self, rot_index ):
        """ Set the sprite image to the correct rotation """
        rot_index %= self.angle_slots
        self.rotation = rot_index
        # Select the pre-rotated image 
        self.image = self.rotations[ rot_index ]
        # We need to preserve the centre-position of the bitmap, 
        # as rotated bitmaps will (probably) not be the same size as the original
        centerx = self.rect.centerx
        centery = self.rect.centery
        self.rect = self.image.get_rect()
        self.rect.center = ( centerx, centery )

    def update( self ):
        self.rotateRight()  # do something

You could of-course pre-make the 12 frames of rotated bitmap in a graphics package, and just load them in at run-time. I like the above method because if you decide to move to say 24 frames, it all happens with the change of a parameter.

The direction the image is "facing" is simply the current index of rotation ( the self.rotation ) in the class above. For example, Imagine a "rotation" with just 4 frames - up/right/down/left.

like image 130
Kingsley Avatar answered Oct 31 '22 22:10

Kingsley