Pygame 2D image animations rendering in the wrong way

6 days ago 8
ARTICLE AD BOX

I have been making a 2D platform game which has a melee attacking system. I have only one attacking animation frame image which is flipped based on the self.direction flag.

The main issue is that when I attack facing right self.direction == 'right', the animation changes normally which gives the optical illusion that the player is extending his sword rightwards, however, when the player faces left, instead of the sword "swinging" to the left, the animation extends to the right, pushing the image rightwards (giving an impression that the player is being pushed back instead of attacking leftwards).

I've tried having AI fixing it for me, I spent days trying to figure this out, but I couldnt. This is the repo as it is for you to have more context:
https://github.com/gabriel-caesar/Python/tree/main/pygame/warrior_travails

Follow the code below:

# ./player.py ... def animate(self): # Handling flipping logic if self.direction == 'right': self.flip = False elif self.direction == 'left': self.flip = True match self.animation_state: case 'run': self.player_frames = [ walk_1, walk_2, walk_3, walk_4 ] self.animation_index += 0.1 if (self.animation_index > len(self.player_frames)): self.animation_index = 0 self.image = pygame.transform.flip(self.player_frames[int(self.animation_index)], self.flip, False) case 'attack': self.player_frames = [ attack_2 ] self.animation_index += 0.1 if (self.animation_index > len(self.player_frames)): self.animation_index = 0 self.image = pygame.transform.flip(self.player_frames[int(self.animation_index)], self.flip, False) case 'guard': self.player_frames = [ guard_1 ] self.image = pygame.transform.flip(self.player_frames[0], self.flip, False) case 'jump': self.player_frames = [ jump_1 ] self.image = pygame.transform.flip(self.player_frames[0], self.flip, False) case 'idle': self.player_frames = [ idle_1 ] self.image = pygame.transform.flip(self.player_frames[0], self.flip, False) self.rect = self.image.get_rect() ...

Now, this is how I draw the player sprite:

# Initializing the player player = Player(400, [800, 250]) playergroup = pygame.sprite.GroupSingle() playergroup.add(player) ... playergroup.draw(screen)

Then in the Player class:

class Player(pygame.sprite.Sprite, Entity): def __init__(self, hp, pos): pygame.sprite.Sprite.__init__(self) Entity.__init__(self, hp, pos) # Animation flags self.animation_state = 'idle' self.animation_index = 0 self.player_frames = [] # Sprite rect and image self.image = idle_1 self.rect = self.image.get_rect(midbottom = (pos[0], pos[1])) ...

If you want more context, this is the Entity class:

class Entity(): def __init__(self, hp, pos): self.hp = hp self.pos = pos self.vertical_velocity = 0 self.movement = [0, 0] self.air_timer = 0 self.flip = False self.direction = 'right' self.guarding = False self.attacking = False self.attack_cooldown = 0

For when the self.attacking becomes true by pressing the letter k on the keyboard, animation_state becomes 'attack', then self.player_frames will have load the attacking image, blit it and based on self.flip, the code will flip it

Read Entire Article