0

I recently managed to give the main character in my game some animations. the animations work fine, but I noticed a problem. whenever I release the key for the animation, the sprite disappears for a very small amount of time, before coming back. can someone please tell me why this is happening? I've tried everything I know of, like increasing the framerate, but the flickering still persists.

here's my code for the player class(the main loop runs at 60 frames/second):

# player setup
scale_by = 4
class Player:
    def __init__(self):
        # loading the images
        self.image = pygame.image.load('Assets/Player/Player.png').convert()
        self.width = (self.image.get_width() * scale_by)
        self.height = (self.image.get_height() * scale_by)
        self.sprite = pygame.transform.scale(self.image, (self.width, self.height))
        with open('Assets/Player/Player.json') as data:
            sprite_Data = data.read()
            self.spriteData = json.loads(sprite_Data)
        data.close()

        # lists for different animations and variables for things
        # idle animations list
        self.idle_right_frames = []
        self.idle_left_frames = []
        self.idle_back_frames = []
        self.idle_front_frames = []

        # walking animations list
        self.walking_right_frames = []
        self.walking_left_frames = []
        self.walking_back_frames = []
        self.walking_front_frames = []

        self.current_sprite = 0
        self.animationspeed = 0.05
        self.dir_x = 0
        self.dir_y = -1
        self.posX = 50
        self.posY = 60
        self.speed = 2
        self.idleanim = True

        # idle frames appending
        self.frames_append('plr_idle_right', 'frame_1', 'frame_2', 'frame_3', 
                                                     self.idle_right_frames)
        self.frames_append('plr_idle_left', 'frame_1', 'frame_2', 'frame_3', 
                                                      self.idle_left_frames)
        self.frames_append('plr_idle_back', 'frame_1', 'frame_2', 'frame_3', 
                                                        self.idle_back_frames)
        self.frames_append('plr_idle_front', 'frame_1', 'frame_2', 'frame_3', 
                                                         self.idle_front_frames)
        # walking frames appending
        self.frames_append('plr_walking_right', 'frame_1', 'frame_2', 'frame_3', 
                                                    self.walking_right_frames)
        self.frames_append('plr_walking_left', 'frame_1', 'frame_2', 'frame_3', 
                                                      self.walking_left_frames)
        self.frames_append('plr_walking_back', 'frame_1', 'frame_2', 'frame_3', 
                                                        self.walking_back_frames)
        self.frames_append('plr_walking_front', 'frame_1', 'frame_2', 'frame_3', 
                                               self.walking_front_frames)

    def player_draw(self, X, Y, W, H):
        sprite_surface = pygame.Surface((W, H))
        sprite_surface.set_colorkey(BLACK)
        sprite_surface.blit(self.sprite, (0, 0), (X, Y, W, H))
        return sprite_surface

    def plr_frame_coords(self, frame_dict, frame_no):
        coordinates = self.spriteData['player'][frame_dict][frame_no]
        X, Y, W, H = int(coordinates['X'] * scale_by), int(coordinates['Y'] * scale_by), \
                     int(coordinates['W'] * scale_by), int(coordinates['H'] * scale_by)
        return X, Y, W, H

    def frames_append(self, animation_name, frame1, frame2, frame3, frame_list):
        coordinates_1 = self.plr_frame_coords(animation_name, frame1)
        frame_1 = self.player_draw(coordinates_1[0], coordinates_1[1],
                                   coordinates_1[2], coordinates_1[3])
        
        coordinates_2 = self.plr_frame_coords(animation_name, frame2)
        
        frame_2 = self.player_draw(coordinates_2[0], coordinates_2[1],
                                   coordinates_2[2], coordinates_2[3])
        
        coordinates_3 = self.plr_frame_coords(animation_name, frame3)
        
        frame_3 = self.player_draw(coordinates_3[0], coordinates_3[1],
                                   coordinates_3[2], coordinates_3[3])

        frame_list.append(frame_1)
        frame_list.append(frame_2)
        frame_list.append(frame_3)

    def animation(self, direction_x, direction_y, listName):
        if self.dir_y == direction_y and self.dir_x == direction_x and self.idleanim:
            sprite = listName[int(self.current_sprite)]
            self.current_sprite += self.animationspeed
            if self.current_sprite >= len(listName):
                self.current_sprite = 0
            screen.blit(sprite, (self.posX, self.posY))

    def animation_walking(self, direction_x, direction_y, listName):
        if self.dir_y == direction_y and self.dir_x == direction_x and self.idleanim == False:
            sprite = listName[int(self.current_sprite)]
            self.current_sprite += self.animationspeed
            if self.current_sprite >= len(listName):
                self.current_sprite = 0
            screen.blit(sprite, (self.posX, self.posY))

    def player_behaviour(self):
        self.animation(1, 0, self.idle_right_frames)
        self.animation(0, -1, self.idle_front_frames)
        self.animation(0, 1, self.idle_back_frames)
        self.animation(-1, 0, self.idle_left_frames)
        if key_pressed[pygame.K_RIGHT]:
            self.posX += self.speed
            self.idleanim = False
            self.dir_x = 1
            self.dir_y = 0
            self.animation_walking(1, 0, self.walking_right_frames)
        elif key_pressed[pygame.K_LEFT]:
            self.posX += -self.speed
            self.idleanim = False
            self.dir_x = -1
            self.dir_y = 0
            self.animation_walking(-1, 0, self.walking_left_frames)
        elif key_pressed[pygame.K_UP]:
            self.posY += -self.speed
            self.idleanim = False
            self.dir_y = -1
            self.dir_x = 0
            self.animation_walking(0, -1, self.walking_back_frames)
        elif key_pressed[pygame.K_DOWN]:
            self.posY += self.speed
            self.idleanim = False
            self.dir_y = 1
            self.dir_x = 0
            self.animation_walking(0, 1, self.walking_front_frames)
        else:
            self.idleanim = True


    
icekete
  • 25
  • 1
  • 4

1 Answers1

0

This is the problem:

def player_behaviour(self):
            self.animation(1, 0, self.idle_right_frames)
            self.animation(0, -1, self.idle_front_frames)
            self.animation(0, 1, self.idle_back_frames)
            self.animation(-1, 0, self.idle_left_frames)
            #... omitted code
            else:
                self.idleanim = True

self.animation requires self.idleanim to be true to be true to draw the sprites. So if none of the keys are pressed, i.e after you release the key, there will be one frame where the drawing will be skipped.

This is what's happening right now.

idleanim = False
while True:
    if idleanim:
        DrawSprites()
    idleanim = True

You can see why it would skip drawing once. What you want to do is to check the if statements first and then call self.animate

def player_behaviour(self):
      #... omitted code
      else:
          self.idleanim = True
      self.animation(1, 0, self.idle_right_frames)
      self.animation(0, -1, self.idle_front_frames)
      self.animation(0, 1, self.idle_back_frames)
      self.animation(-1, 0, self.idle_left_frames)