0

I’ve been trying to to add a function to a space invaders inspired game I’m creating where I rotate a player that shoots bullets upwards. The player moves left and right using keys w and d, but when trying to rotate it using LEFT and RIGHT keys, it does this strange circular motion then bounces back the other way:

[View this gif to see the movement I mean

Here’s the code:

import pygame
import os

clock = pygame.time.Clock()

#standard variables for universal operation
WIDTH = 610
HEIGHT = 760
WIN = pygame.display.set_mode((WIDTH,HEIGHT))
FPS = 60

BORDER = pygame.Rect(0,720,WIDTH,4)

BLACK = (0,0,0)
WHITE = (255,255,255)
GREEN = (0,200,0) #slightly darker green

PLAYER_IMG = pygame.image.load(os.path.join('src', 'player.png'))
PLAYER_VEL = 5
PLAYER_WIDTH = 36
PLAYER_HEIGHT = 22
INIT_PLAYER_ANGLE = 0
ANGULAR_VEL = 5

BULLET_VEL = 7
MAX_BULLETS = 3
BULLET_WIDTH = 3
BULLET_HEIGHT = 8

def move_player(player, angle):

    #rotation
    keys_pressed = pygame.key.get_pressed()
    if keys_pressed[pygame.K_LEFT]:# and (angle >= -45):
        angle -= ANGULAR_VEL
    if keys_pressed[pygame.K_RIGHT]:# and (angle <= 45):
        angle += ANGULAR_VEL

    rotated = pygame.transform.rotate(PLAYER_IMG,angle)
    player = rotated.get_rect(center=player.center)
    #linear translation
    keys_pressed = pygame.key.get_pressed()
    if (player.x <= WIDTH - 37) and (keys_pressed[pygame.K_d]):
        player.x += PLAYER_VEL
    if (player.x >= 0) and (keys_pressed[pygame.K_a]):
        player.x -= PLAYER_VEL

    return player, angle

def fire_bullet(bullets, player):
    for bullet in bullets:
        bullet.y -= BULLET_VEL

def window(player,bullets,angle):
    WIN.fill(BLACK) #background
    pygame.draw.rect(WIN,GREEN,BORDER) #seperation between game and lower info block
    WIN.blit(PLAYER_IMG,(player.x,player.y)) #player
    for bullet in bullets:
        pygame.draw.rect(WIN,GREEN,bullet) #bullets
    pygame.display.update()

def main():
    player = pygame.Rect(WIDTH/2-PLAYER_WIDTH/2,685,PLAYER_WIDTH,PLAYER_HEIGHT)
    bullets = []
    angle = INIT_PLAYER_ANGLE

    running = True
    while running: #main game loop
        clock.tick(FPS)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False #breaks loop if window is shut by user

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    bullet = pygame.Rect(player.x+PLAYER_WIDTH/2-BULLET_WIDTH/2,player.y+BULLET_HEIGHT,BULLET_WIDTH,BULLET_HEIGHT)
                    bullets.append(bullet)
                
        fire_bullet(bullets,player)
        player, angle = move_player(player,angle)
        window(player,bullets,angle)

    pygame.quit()

if __name__ == "__main__":
    main()
Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
  • You are not using the rotated image in `window`. `pygame.transform.rotate` does not modify `PLAYER_IMG` – MegaIng Apr 13 '23 at 21:36

1 Answers1

1

It looks like you rotate the image, but still blit unrotated one to the screen. So ensure your window() uses rotated one. Also pass the rotated image from the move_player() function to the window() in the main(), because it's created there. Eventually update the move_player() to return the rotated image and that should address your problem.


def move_player(player, angle):
    keys_pressed = pygame.key.get_pressed()
    if keys_pressed[pygame.K_LEFT]:# and (angle >= -45):
        angle -= ANGULAR_VEL
    if keys_pressed[pygame.K_RIGHT]:# and (angle <= 45):
        angle += ANGULAR_VEL

    rotated = pygame.transform.rotate(PLAYER_IMG,angle)
    player = rotated.get_rect(center=player.center)
    ...

    return player, angle, rotated

def window(player,bullets,angle,rotated_image):
    WIN.fill(BLACK)
    pygame.draw.rect(WIN,GREEN,BORDER) 
    WIN.blit(rotated_image,(player.x,player.y))
    for bullet in bullets:
        pygame.draw.rect(WIN,GREEN,bullet) 
    pygame.display.update()

def main():
    ...

    while running: #main game loop
        ...

        player, angle, rotated = move_player(player,angle)
        window(player,bullets,angle,rotated)

    pygame.quit()
Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141