首页 > 解决方案 > 当我在pygame中的不同动画之间切换时精灵闪烁

问题描述

我最近设法给我游戏中的主角一些动画。动画效果很好,但我注意到了一个问题。每当我释放动画的键时,精灵就会消失一小段时间,然后再回来。有人可以告诉我为什么会这样吗?我已经尝试了我所知道的一切,比如提高帧率,但闪烁仍然存在。

这是我的播放器类代码(主循环以 60 帧/秒的速度运行):

# 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


    

标签: pythonpygame

解决方案


这就是问题:

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需要self.idleanim为真才能绘制精灵。因此,如果没有按下任何键,即松开键后,将跳过一帧绘图。

这就是现在正在发生的事情。

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

您可以看到为什么它会跳过一次绘图。您要做的是先检查 if 语句,然后调用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)
   

推荐阅读