为什么我的左右移动动画不起作用?
Why does my animation for moving left and right not work?
我正在努力让我的角色有一个行走动画,但由于某些原因,左右动画不起作用,尽管我的上下行走动画可以。每当我向左或向右移动时,它都会翻转我的角色,就好像他在向上走一样,但它也不会播放向上的动画。我已经查看了代码一百万次,但我没有发现向上和向下动画的方式与向左和向右设置的方式有任何区别,所以我只是不知道哪里出了问题。下面我写出了播放器 class 的代码,因为我 99% 确定问题出在其中。我还会记录问题在游戏中出现的 gif 动图,并把整个代码放在一个 pastebin 中,以防 Player class 不够用。 https://pastebin.com/968pjEmc https://gyazo.com/0dedfae143497bbc4062cf802e18d054
class Player(pygame.sprite.Sprite):
""" This class represents the character you play as """
def __init__(self, x, y):
""" Constructor function """
# Call the parent's constructor
super().__init__()
self.change_x = 0
self.change_y = 0
self.walking_frames_l = []
self.walking_frames_r = []
self.walking_frames_u = []
self.walking_frames_d = []
self.direction = "R"
sprite_sheet = SpriteSheet("character.png")
image = sprite_sheet.get_image(1, 6, 15, 22)
self.walking_frames_d.append(image)
image = sprite_sheet.get_image(17, 6, 15, 22)
self.walking_frames_d.append(image)
image = sprite_sheet.get_image(33, 6, 15, 22)
self.walking_frames_d.append(image)
image = sprite_sheet.get_image(49, 6, 15, 22)
self.walking_frames_d.append(image)
image = sprite_sheet.get_image(0, 69, 15, 23)
self.walking_frames_u.append(image)
image = sprite_sheet.get_image(16, 69, 15, 23)
self.walking_frames_u.append(image)
image = sprite_sheet.get_image(32, 69, 15, 23)
self.walking_frames_u.append(image)
image = sprite_sheet.get_image(48, 69, 15, 23)
self.walking_frames_u.append(image)
image = sprite_sheet.get_image(2, 38, 13, 22)
self.walking_frames_r.append(image)
image = sprite_sheet.get_image(18, 38, 13, 22)
self.walking_frames_r.append(image)
image = sprite_sheet.get_image(34, 38, 13, 22)
self.walking_frames_r.append(image)
image = sprite_sheet.get_image(50, 38, 13, 22)
self.walking_frames_r.append(image)
image = sprite_sheet.get_image(1, 102, 13, 22)
self.walking_frames_l.append(image)
image = sprite_sheet.get_image(17, 102, 13, 22)
self.walking_frames_l.append(image)
image = sprite_sheet.get_image(33, 102, 13, 22)
self.walking_frames_l.append(image)
image = sprite_sheet.get_image(49, 102, 13, 22)
self.walking_frames_l.append(image)
self.image = self.walking_frames_r[0]
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
def move(self, walls):
""" Moves player """
# Move left/right
self.change_x = 0
pos = self.rect.x
keystate = pygame.key.get_pressed()
if keystate[pygame.K_a]:
self.change_x = -8
self.direction = "L"
if keystate[pygame.K_d]:
self.change_x = 8
self.direction = "R"
self.rect.x += self.change_x
if self.direction == "R":
frame = (pos // 30) % len(self.walking_frames_r)
self.image = self.walking_frames_r[frame]
else:
frame = (pos // 30) % len(self.walking_frames_l)
self.image = self.walking_frames_l[frame]
# Did this update cause us to hit a wall?
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
# If we are moving right, set our right side to the left side of
# the item we hit
if self.change_x > 0:
self.rect.right = block.rect.left
else:
# Otherwise if we are moving left, do the opposite.
self.rect.left = block.rect.right
# Move up/down
self.change_y = 0
pos = self.rect.y
keystate = pygame.key.get_pressed()
if keystate[pygame.K_w]:
self.change_y = -8
self.direction = "U"
if keystate[pygame.K_s]:
self.change_y = 8
self.direction = "D"
self.rect.y += self.change_y
if self.direction == "D":
frame = (pos // 30) % len(self.walking_frames_d)
self.image = self.walking_frames_d[frame]
else:
frame = (pos // 30) % len(self.walking_frames_u)
self.image = self.walking_frames_u[frame]
# Check and see if we hit anything
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
# Reset our position based on the top/bottom of the object.
if self.change_y > 0:
self.rect.bottom = block.rect.top
else:
self.rect.top = block.rect.bottom
它不起作用,因为如果 self.direction
不是 "D"
那么 self.image
在任何情况下都由 self.walking_frames_u[frame]
设置。
注意,下面语句中的 else
case 总是被执行,即使 self.direction
是 "L"
或 "R"
:
if self.direction == "D":
frame = (pos // 30) % len(self.walking_frames_d)
self.image = self.walking_frames_d[frame]
else:
frame = (pos // 30) % len(self.walking_frames_u)
self.image = self.walking_frames_u[frame]
将设置 self.image
的代码合并到一个 if
-elif
-else
语句中。
此外,您必须确保使用正确的坐标来计算图像索引。去掉变量pos
,分别用self.rect.x
代替self.rect.y
:
if self.direction == "R":
frame = (self.rect.x // 30) % len(self.walking_frames_r)
self.image = self.walking_frames_r[frame]
elif self.direction == "L":
frame = (self.rect.x // 30) % len(self.walking_frames_l)
self.image = self.walking_frames_l[frame]
elif self.direction == "D":
frame = (self.rect.y // 30) % len(self.walking_frames_d)
self.image = self.walking_frames_d[frame]
elif:
frame = (self.rect.y // 30) % len(self.walking_frames_u)
self.image = self.walking_frames_u[frame]
我正在努力让我的角色有一个行走动画,但由于某些原因,左右动画不起作用,尽管我的上下行走动画可以。每当我向左或向右移动时,它都会翻转我的角色,就好像他在向上走一样,但它也不会播放向上的动画。我已经查看了代码一百万次,但我没有发现向上和向下动画的方式与向左和向右设置的方式有任何区别,所以我只是不知道哪里出了问题。下面我写出了播放器 class 的代码,因为我 99% 确定问题出在其中。我还会记录问题在游戏中出现的 gif 动图,并把整个代码放在一个 pastebin 中,以防 Player class 不够用。 https://pastebin.com/968pjEmc https://gyazo.com/0dedfae143497bbc4062cf802e18d054
class Player(pygame.sprite.Sprite):
""" This class represents the character you play as """
def __init__(self, x, y):
""" Constructor function """
# Call the parent's constructor
super().__init__()
self.change_x = 0
self.change_y = 0
self.walking_frames_l = []
self.walking_frames_r = []
self.walking_frames_u = []
self.walking_frames_d = []
self.direction = "R"
sprite_sheet = SpriteSheet("character.png")
image = sprite_sheet.get_image(1, 6, 15, 22)
self.walking_frames_d.append(image)
image = sprite_sheet.get_image(17, 6, 15, 22)
self.walking_frames_d.append(image)
image = sprite_sheet.get_image(33, 6, 15, 22)
self.walking_frames_d.append(image)
image = sprite_sheet.get_image(49, 6, 15, 22)
self.walking_frames_d.append(image)
image = sprite_sheet.get_image(0, 69, 15, 23)
self.walking_frames_u.append(image)
image = sprite_sheet.get_image(16, 69, 15, 23)
self.walking_frames_u.append(image)
image = sprite_sheet.get_image(32, 69, 15, 23)
self.walking_frames_u.append(image)
image = sprite_sheet.get_image(48, 69, 15, 23)
self.walking_frames_u.append(image)
image = sprite_sheet.get_image(2, 38, 13, 22)
self.walking_frames_r.append(image)
image = sprite_sheet.get_image(18, 38, 13, 22)
self.walking_frames_r.append(image)
image = sprite_sheet.get_image(34, 38, 13, 22)
self.walking_frames_r.append(image)
image = sprite_sheet.get_image(50, 38, 13, 22)
self.walking_frames_r.append(image)
image = sprite_sheet.get_image(1, 102, 13, 22)
self.walking_frames_l.append(image)
image = sprite_sheet.get_image(17, 102, 13, 22)
self.walking_frames_l.append(image)
image = sprite_sheet.get_image(33, 102, 13, 22)
self.walking_frames_l.append(image)
image = sprite_sheet.get_image(49, 102, 13, 22)
self.walking_frames_l.append(image)
self.image = self.walking_frames_r[0]
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
def move(self, walls):
""" Moves player """
# Move left/right
self.change_x = 0
pos = self.rect.x
keystate = pygame.key.get_pressed()
if keystate[pygame.K_a]:
self.change_x = -8
self.direction = "L"
if keystate[pygame.K_d]:
self.change_x = 8
self.direction = "R"
self.rect.x += self.change_x
if self.direction == "R":
frame = (pos // 30) % len(self.walking_frames_r)
self.image = self.walking_frames_r[frame]
else:
frame = (pos // 30) % len(self.walking_frames_l)
self.image = self.walking_frames_l[frame]
# Did this update cause us to hit a wall?
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
# If we are moving right, set our right side to the left side of
# the item we hit
if self.change_x > 0:
self.rect.right = block.rect.left
else:
# Otherwise if we are moving left, do the opposite.
self.rect.left = block.rect.right
# Move up/down
self.change_y = 0
pos = self.rect.y
keystate = pygame.key.get_pressed()
if keystate[pygame.K_w]:
self.change_y = -8
self.direction = "U"
if keystate[pygame.K_s]:
self.change_y = 8
self.direction = "D"
self.rect.y += self.change_y
if self.direction == "D":
frame = (pos // 30) % len(self.walking_frames_d)
self.image = self.walking_frames_d[frame]
else:
frame = (pos // 30) % len(self.walking_frames_u)
self.image = self.walking_frames_u[frame]
# Check and see if we hit anything
block_hit_list = pygame.sprite.spritecollide(self, walls, False)
for block in block_hit_list:
# Reset our position based on the top/bottom of the object.
if self.change_y > 0:
self.rect.bottom = block.rect.top
else:
self.rect.top = block.rect.bottom
它不起作用,因为如果 self.direction
不是 "D"
那么 self.image
在任何情况下都由 self.walking_frames_u[frame]
设置。
注意,下面语句中的 else
case 总是被执行,即使 self.direction
是 "L"
或 "R"
:
if self.direction == "D": frame = (pos // 30) % len(self.walking_frames_d) self.image = self.walking_frames_d[frame] else: frame = (pos // 30) % len(self.walking_frames_u) self.image = self.walking_frames_u[frame]
将设置 self.image
的代码合并到一个 if
-elif
-else
语句中。
此外,您必须确保使用正确的坐标来计算图像索引。去掉变量pos
,分别用self.rect.x
代替self.rect.y
:
if self.direction == "R":
frame = (self.rect.x // 30) % len(self.walking_frames_r)
self.image = self.walking_frames_r[frame]
elif self.direction == "L":
frame = (self.rect.x // 30) % len(self.walking_frames_l)
self.image = self.walking_frames_l[frame]
elif self.direction == "D":
frame = (self.rect.y // 30) % len(self.walking_frames_d)
self.image = self.walking_frames_d[frame]
elif:
frame = (self.rect.y // 30) % len(self.walking_frames_u)
self.image = self.walking_frames_u[frame]