How to rotate image while moving in pygame

Viewed 91

I am new to pygame and trying to develop a game in which the player moves with arrow keys and rotates around with the position of mouse (like mini miltia). But I am able to rotate the player but not able to move it around. It is only showing the player with rotation but it is not moving.

def rot_center(image, rect, angle):

    rot_image = pygame.transform.rotate(image, angle)
    rot_rect = rot_image.get_rect(center=rect.center)
    return rot_image, rot_rect

class Player(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image_orig = load_image('player.png')
        self.image = self.image_orig
        self.rect = self.image.get_rect()
        self.rect_orig = self.rect
        self.mask = pygame.mask.from_surface(self.image)
        self.x, self.y = int(pygame.display.Info().current_w / 2), int(pygame.display.Info().current_h / 2)
        self.rect.topleft = self.x, self.y
        self.health = 100
        self.damage_done = 0
        self.chspeed_x = 10
        self.chspeed_y = 10
        self.dir = 0

    def rot_aim(self, tx, ty):
        self.dir = (math.atan2(self.y - ty, self.x - tx) * 180 / PI)
        self.image, self.rect = rot_center(self.image_orig, self.rect_orig, self.dir)

    def move(self, dx, dy):
        self.chspeed_x = dx
        self.chspeed_y = dy
        self.x = self.x + self.chspeed_x * math.cos(math.radians(270 - self.dir))
        self.y = self.y + self.chspeed_y * math.cos(math.radians(270 - self.dir))

def main():

    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    clock = pygame.time.Clock()
    FPS = 30
    paused = False
    player = Player()

    player_s = pygame.sprite.Group()

    player_s.add(player)

    while not paused:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.MOUSEMOTION:
                mousepos = pygame.mouse.get_pos()
                mouseX = mousepos[0]
                mouseY = mousepos[1]
                player.rot_aim(mousepos[1], mousepos[0])
            if event.type == pygame.KEYDOWN:
                if event.type == pygame.K_UP:
                    player.move(0, 10)
                if event.type == pygame.K_DOWN:
                    player.move(0, -10)
                if event.type == pygame.K_RIGHT:
                    player.move(10, 0)
                if event.type == pygame.K_LEFT:
                    player.move(-10, 0)

        player_s.draw(screen)
        clock.tick(FPS)
        pygame.display.flip()
1 Answers

You missed to update self.rect after rotating or moving the player. Actually the position of the player (self.x, self.y) is changed. But since self.rect is used to draw the player, this attribute has to be updated by the position. The position has to be round, because a pygame.Rect object stores integral values:

class Player(pygame.sprite.Sprite):
    # [...]

    def rot_aim(self, tx, ty):
        self.dir = (math.atan2(self.y - ty, self.x - tx) * 180 / PI)
        self.image, self.rect = rot_center(self.image_orig, self.rect_orig, self.dir)

        self.rect.center = round(self.x), round(self.y) # <--- this is missing

    def move(self, dx, dy):
        self.chspeed_x = dx
        self.chspeed_y = dy
        self.x = self.x + self.chspeed_x * math.cos(math.radians(270 - self.dir))
        self.y = self.y + self.chspeed_y * math.cos(math.radians(270 - self.dir))

        self.rect.center= round(self.x), round(self.y) # <--- this is missing

Further more there is a typo. You have to compare event.key to the button rather than event.type

For instance:

if event.type == pygame.K_UP:

if event.key == pygame.K_UP:
    # [...]

Anyway I recommend to use pygame.key.get_pressed() rather than the button events, to achieve a continuously and smooth movement.
Finally clear the background by screen.fill(0) before drawing the scene:

def main():

    # [...]

    while not paused:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.MOUSEMOTION:
                mousepos = pygame.mouse.get_pos()
                mouseX = mousepos[0]
                mouseY = mousepos[1]
                player.rot_aim(mousepos[1], mousepos[0])

        keys = pygame.key.get_pressed()
        if keys[pygame.K_UP]:
            player.move(0, -10)
        if keys[pygame.K_DOWN]:
            player.move(0, 10)
        if keys[pygame.K_RIGHT]:
            player.move(10, 0)
        if keys[pygame.K_LEFT]:
            player.move(-10, 0)

        screen.fill(0)
        player_s.draw(screen)
        clock.tick(FPS)
        pygame.display.flip()
Related