淘先锋技术网

首页 1 2 3 4 5 6 7

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

结果如下:

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

项目结构目录

 角色类

import os
import pygame,sys
dir = "persent/magic/"

class Hero(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.kinds = ["attack","hit","idle","miss"]  # 角色的所有动作
        self.state = 'idle'   # 当前状态
        self.current_frame = -1  # 当前动作序列的到第几张
        self.current_image = None # 当前动作序列对应的图片
        self.all_frame = {}  # 所有的动作,表现为"动作名称":动作序列
        self.frames = []    # 当前动作序列
        self.last_updated = 0  #更新的时间


    # 设置绘制的主屏幕,上层传入
    def setScreen(self,screen):
        self.screen = screen

    #更新动作
    def update(self):
        self.handle_state()   # 切换动作
        self.animate()     # 连贯一个动作
        self.screen.blit(self.current_image,self.rect)# 绘制
    # 切换当前动作的序列帧
    def animate(self):
        now = pygame.time.get_ticks()
        if now - self.last_updated > 100:
            self.last_updated = now
            self.current_frame = (self.current_frame + 1) % len(self.frames)
            self.current_image = self.frames[self.current_frame]
    # 初始化时加载图片
    def load_image(self):

        listName = "hero"+str(self.ID)  # 人物文件夹名字
        for i in self.kinds:   # 任务文件夹下面的几个动作名字
            self.all_frame.setdefault(i,[])   # 设置"动作名":列表
            frames = os.listdir(dir+listName+'/'+i)  # 获取动作的所有图片名字
            for j in frames:  # 遍历所有图片
                filename = dir+listName+'/'+i+'/'+j  # 组装成对应可以读取名字
                print(filename)
                # 读取图片
                self.all_frame[i].append(
                    pygame.image.load(filename)
                )
        self.state = self.kinds[2]  # 将状态切换为idle
        self.handle_state()    # 更新对应序列
        self.current_frame = 0 # 重置当前帧
        self.current_image = self.all_frame.get('idle')[0]  # 设置当前图片
        self.rect = self.all_frame.get('idle')[0].get_rect() # 获取图片对应
        self.rect.midbottom = (100,100)# 设置图片大小
        # 设置图片位置
        self.rect.x = 100  
        self.rect.y = 100
    # 更换当前动作状态序列帧
    def handle_state(self):
        if self.state == 'idle':
            self.frames = self.all_frame.get("idle")
        elif self.state == "hit":
            self.frames = self.all_frame.get("hit")
        elif self.state == "miss":
            self.frames = self.all_frame.get("miss")
        elif self.state == "attack":
            self.frames = self.all_frame.get("attack")

    # ["attack","hit","idle","miss"] 改变角色状态
    def changeState(self,num:int):
        if num >0 and num<len(self.kinds):# 在规定的状态里面
            if self.state != self.kinds[num]:# 状态改变
                self.current_frame = 0
            self.state = self.kinds[num]  # 修改状态

角色生成类:


class heroProduct:
    def __init__(self,screen):
        self.screen = screen


    # 创建一个人物
    def createHero(self):
        hero = Hero()
        hero.setScreen(screen)
        hero.load_image()
        return hero

代码入口

import pygame
import persent.script.Heroproduct as Heroproduct
import persent.script.AbilityManage as AbilityManage


pygame.init()
pygame.display.set_caption("hight")  # 设置窗口名字
screen_width, screen_height = 560, 780   # 设置窗口大小
screen = pygame.display.set_mode((screen_width, screen_height))
clock = pygame.time.Clock()  # 设置时钟


heroproduct = Heroproduct.heroProduct(screen)

hero = heroproduct.createHero()
start = True
while start:
    clock.tick(60)
    hero.update()
    for event in pygame.event.get():  # 循环获取事件
        if event.type == pygame.QUIT:  # 若检测到事件类型为退出,则退出系统
            start = False
        if event.type == pygame.KEYDOWN:
            # 具体是哪一个按键的处理
            if event.key == pygame.K_0:
                hero.changeState(0)
            elif event.key == pygame.K_1:
                hero.changeState(1)
            elif event.key == pygame.K_2:
                hero.changeState(2)
            elif event.key == pygame.K_3:
                hero.changeState(3)
    pygame.display.update()  # 更新屏幕内容
pygame.quit()

结果如下:

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

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

问题解决