• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

python3.8.8 pygame实现角色动画

武飞扬头像
长度735
帮助1

用途:通过不同的序列图片在界面上展示连贯的动画

结果如下:

学新通

 参考文章:pygame之旅 - 知乎 (zhihu.com)

项目结构目录

学新通

 角色类

  1.  
    import os
  2.  
    import pygame,sys
  3.  
    dir = "persent/magic/"
  4.  
     
  5.  
    class Hero(pygame.sprite.Sprite):
  6.  
    def __init__(self):
  7.  
    super().__init__()
  8.  
    self.kinds = ["attack","hit","idle","miss"] # 角色的所有动作
  9.  
    self.state = 'idle' # 当前状态
  10.  
    self.current_frame = -1 # 当前动作序列的到第几张
  11.  
    self.current_image = None # 当前动作序列对应的图片
  12.  
    self.all_frame = {} # 所有的动作,表现为"动作名称":动作序列
  13.  
    self.frames = [] # 当前动作序列
  14.  
    self.last_updated = 0 #更新的时间
  15.  
     
  16.  
     
  17.  
    # 设置绘制的主屏幕,上层传入
  18.  
    def setScreen(self,screen):
  19.  
    self.screen = screen
  20.  
     
  21.  
    #更新动作
  22.  
    def update(self):
  23.  
    self.handle_state() # 切换动作
  24.  
    self.animate() # 连贯一个动作
  25.  
    self.screen.blit(self.current_image,self.rect)# 绘制
  26.  
    # 切换当前动作的序列帧
  27.  
    def animate(self):
  28.  
    now = pygame.time.get_ticks()
  29.  
    if now - self.last_updated > 100:
  30.  
    self.last_updated = now
  31.  
    self.current_frame = (self.current_frame 1) % len(self.frames)
  32.  
    self.current_image = self.frames[self.current_frame]
  33.  
    # 初始化时加载图片
  34.  
    def load_image(self):
  35.  
     
  36.  
    listName = "hero" str(self.ID) # 人物文件夹名字
  37.  
    for i in self.kinds: # 任务文件夹下面的几个动作名字
  38.  
    self.all_frame.setdefault(i,[]) # 设置"动作名":列表
  39.  
    frames = os.listdir(dir listName '/' i) # 获取动作的所有图片名字
  40.  
    for j in frames: # 遍历所有图片
  41.  
    filename = dir listName '/' i '/' j # 组装成对应可以读取名字
  42.  
    print(filename)
  43.  
    # 读取图片
  44.  
    self.all_frame[i].append(
  45.  
    pygame.image.load(filename)
  46.  
    )
  47.  
    self.state = self.kinds[2] # 将状态切换为idle
  48.  
    self.handle_state() # 更新对应序列
  49.  
    self.current_frame = 0 # 重置当前帧
  50.  
    self.current_image = self.all_frame.get('idle')[0] # 设置当前图片
  51.  
    self.rect = self.all_frame.get('idle')[0].get_rect() # 获取图片对应
  52.  
    self.rect.midbottom = (100,100)# 设置图片大小
  53.  
    # 设置图片位置
  54.  
    self.rect.x = 100
  55.  
    self.rect.y = 100
  56.  
    # 更换当前动作状态序列帧
  57.  
    def handle_state(self):
  58.  
    if self.state == 'idle':
  59.  
    self.frames = self.all_frame.get("idle")
  60.  
    elif self.state == "hit":
  61.  
    self.frames = self.all_frame.get("hit")
  62.  
    elif self.state == "miss":
  63.  
    self.frames = self.all_frame.get("miss")
  64.  
    elif self.state == "attack":
  65.  
    self.frames = self.all_frame.get("attack")
  66.  
     
  67.  
    # ["attack","hit","idle","miss"] 改变角色状态
  68.  
    def changeState(self,num:int):
  69.  
    if num >0 and num<len(self.kinds):# 在规定的状态里面
  70.  
    if self.state != self.kinds[num]:# 状态改变
  71.  
    self.current_frame = 0
  72.  
    self.state = self.kinds[num] # 修改状态
学新通

角色生成类:

  1.  
     
  2.  
    class heroProduct:
  3.  
    def __init__(self,screen):
  4.  
    self.screen = screen
  5.  
     
  6.  
     
  7.  
    # 创建一个人物
  8.  
    def createHero(self):
  9.  
    hero = Hero()
  10.  
    hero.setScreen(screen)
  11.  
    hero.load_image()
  12.  
    return hero

代码入口

  1.  
    import pygame
  2.  
    import persent.script.Heroproduct as Heroproduct
  3.  
    import persent.script.AbilityManage as AbilityManage
  4.  
     
  5.  
     
  6.  
    pygame.init()
  7.  
    pygame.display.set_caption("hight") # 设置窗口名字
  8.  
    screen_width, screen_height = 560, 780 # 设置窗口大小
  9.  
    screen = pygame.display.set_mode((screen_width, screen_height))
  10.  
    clock = pygame.time.Clock() # 设置时钟
  11.  
     
  12.  
     
  13.  
    heroproduct = Heroproduct.heroProduct(screen)
  14.  
     
  15.  
    hero = heroproduct.createHero()
  16.  
    start = True
  17.  
    while start:
  18.  
    clock.tick(60)
  19.  
    hero.update()
  20.  
    for event in pygame.event.get(): # 循环获取事件
  21.  
    if event.type == pygame.QUIT: # 若检测到事件类型为退出,则退出系统
  22.  
    start = False
  23.  
    if event.type == pygame.KEYDOWN:
  24.  
    # 具体是哪一个按键的处理
  25.  
    if event.key == pygame.K_0:
  26.  
    hero.changeState(0)
  27.  
    elif event.key == pygame.K_1:
  28.  
    hero.changeState(1)
  29.  
    elif event.key == pygame.K_2:
  30.  
    hero.changeState(2)
  31.  
    elif event.key == pygame.K_3:
  32.  
    hero.changeState(3)
  33.  
    pygame.display.update() # 更新屏幕内容
  34.  
    pygame.quit()
学新通

结果如下:

学新通

 发现出现问题,动画出现残影,看网上说需要先绘制背景,再绘制角色可以解决,随意填个颜色screen.fill(255)

  1.  
    while start:
  2.  
    clock.tick(60)
  3.  
    screen.fill(255)
  4.  
    hero.update()
  5.  
    pygame.display.update() # 更新屏幕内容
  6.  
    for event in pygame.event.get(): # 循环获取事件
  7.  
    if event.type == pygame.QUIT: # 若检测到事件类型为退出,则退出系统
  8.  
    start = False
  9.  
    if event.type == pygame.KEYDOWN:
  10.  
    # 具体是哪一个按键的处理
  11.  
    if event.key == pygame.K_0:
  12.  
    hero.changeState(0)
  13.  
    elif event.key == pygame.K_1:
  14.  
    hero.changeState(1)
  15.  
    elif event.key == pygame.K_2:
  16.  
    hero.changeState(2)
  17.  
    elif event.key == pygame.K_3:
  18.  
    hero.changeState(3)
学新通

问题解决

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggeach
系列文章
更多 icon
同类精品
更多 icon
继续加载