上一节学习如何利用spritesheet加载图片,但是player仍然是一张静态的图片,比较枯燥,我们要让它动起来!
Player类,先把各种状态的图片加载起来:
1 # 加载各种状态的图片序列 2 def load_images(self): 3 # 站立状态的图片 4 self.standing_frames = [self.game.spritesheet.get_image("bunny1_ready.png"), 5 self.game.spritesheet.get_image("bunny1_stand.png")] 6 7 # 向右走的图片 8 self.walking_frames_right = [self.game.spritesheet.get_image("bunny1_walk1.png"), 9 self.game.spritesheet.get_image("bunny1_walk2.png")] 10 11 # 向左走的图片 12 self.walking_frames_left = [] 13 for frame in self.walking_frames_right: 14 # 向左走的图片,只需要把向"右"走的图片,水平(x)方向翻转即可 15 self.walking_frames_left.append(pg.transform.flip(frame, True, False)) 16 17 # 跳跃状态的图片 18 self.jump_frame = self.game.spritesheet.get_image("bunny1_jump.png")
然后要有一些bool型的状态变化(不然,我们就无法知道当前角色是在jump,还是在walk,或是stand)
1 class Player(pg.sprite.Sprite): 2 3 def __init__(self, game): 4 pg.sprite.Sprite.__init__(self) 5 self.game = game 6 # 是否在行走状态 7 self.walking = False 8 # 是否处于跳跃状态 9 self.jumping = False 10 # 当前状态的动画,显示的是哪一"帧" 11 self.current_frame = 0 12 # 当前状态的动画,最后一次切换是什么时候? 13 self.last_update = 0 14 # 加载图片 15 self.load_images() 16 # 初始状态为"站立" 17 self.image = self.standing_frames[0] 18 19 ...
注:current_frame变量的作用,解释一下,一个状态下的图片可能有多张,需要知道当前切换到了第几张,这个变量保存的就是第几张图片的N值。另外一个变量last_update后面会讲到,这里先不用管。
当player向上跳起时,要切换jump的状态:
1 def jump(self): 2 hits = pg.sprite.spritecollide(self, self.game.platforms, False) 3 if hits: 4 self.vel.y = -PLAYER_JUMP 5 # 修改跳跃状态 6 self.jumping = True
为了方便统一处理角色的动画效果,在Player类中新增一个animation函数:
# 动画处理 def animate(self): now = pg.time.get_ticks() # 更新walking状态 if self.vel.x != 0: self.walking = True else: self.walking = False # 垂直方向速度为0,认为未跳跃 if abs(self.vel.y) < 0.5: self.jumping = False # 切换jumping图片 if self.jumping: self.image = self.jump_frame else: self.image = self.standing_frames[0] if not self.jumping and not self.walking: # 调节这里的200,可以控制动画的播放速度 if now - self.last_update > 200: self.last_update = now self.current_frame += 1 # bunny1_ready.png与bunny1_stand.png的高度不同,所以切换后,要调整bottom值,保证图片的最下边缘正好站在档板上 old_bottom = self.rect.bottom self.image = self.standing_frames[self.current_frame % len(self.standing_frames)] self.rect = self.image.get_rect() self.rect.bottom = old_bottom
last_update变量的作用,在animation中就体现出来了,这个变量结合当前时间,算出差值,可以控制每隔多少毫秒切换1次图片。相当于,控制角色动画的播放速度。
最后在update函数中,调用animation:
def update(self): # 动画处理 self.animate() self.acc = vec(0, PLAYER_GRAVITY) keys = pg.key.get_pressed() if keys[pg.K_LEFT]: self.acc.x = -PLAYER_ACC if keys[pg.K_RIGHT]: self.acc.x = PLAYER_ACC self.acc.x += self.vel.x * PLAYER_FRICTION self.vel += self.acc self.pos += self.vel # 因为walking状态的切换,依赖于x速度是否为0判断,当x在0左右的极小值摆动时,会导致判断出错 if abs(self.vel.x) < 0.5: self.vel.x = 0 ...