python - 当我在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
解决方案
这就是问题:
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)
推荐阅读
- javascript - Bootstrap 多级下拉菜单不会自动关闭
- kubernetes - Kubernetes 上的 Corda RPC 连接
- if-statement - 在 Excel 中使用连接和舍入的 IF 语句
- python - 将 float64 转换为日期
- installshield - 无法使用 Installshield 2019 打开 .ism 和 .uip 文件
- shell - 为每个单词的第一个字符加上括号
- python - 如何将其放入 python 中,以便它可以使用掩码随机循环?
- xml - 如何从具有相同名称的节点中获取最后一个值
- javascript - 使用 node.js 渲染 svg 路径数据服务器端
- python - 将值数组传播到函数调用中的参数