• pygame-KidsCanCode系列jumpy-part10-角色动画(上)


    上一节学习如何利用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")
    View Code

    然后要有一些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         ...
    View Code

    注: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
    View Code

     为了方便统一处理角色的动画效果,在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
    View Code

    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
            ...
    View Code

  • 相关阅读:
    C++11并发内存模型学习
    C++0x对局部静态初始化作出了线程安全的要求,singleton的写法可以回归到最原始的方式
    两次fopen不同的文件返回相同的FILE* 地址
    linux kernel kill jvm
    打印Exception信息
    java map value 排序
    java was started but returned exit code 1
    hive 建表语句
    hadoop mapreduce lzo
    分词 正文提取 java
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/pygame-kidscancode-part10-animation-1.html
Copyright © 2020-2023  润新知