欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

cocos2dx-lua 序列帧动画Animation

程序员文章站 2022-03-16 21:45:41
...

简介

Cocos2d-x中,动画的具体内容是依靠精灵显示出来的,为了显示动态图片,我们需要不停切换精灵显示的内容,通过把静态的精灵变为动画播放器从而实现动画效果。动画由帧组成,每一帧都是一个纹理,我们可以使用一个纹理序列来创建动画。

我们使用Animation类描述一个动画,而精灵显示动画的动作则是一个Animate对象。动画动作Animate是精灵显示动画的动作,它由一个动画对象创建,并由精灵执行。

需要了解的几个类:

  • SpriteFrame:精灵帧类。精灵帧包含了对应纹理在大的纹理区域中的位置和大小, 对应纹理是否经过旋转和偏移。根据这些几何信息,可以从大的纹理中找到正确的纹理区域作为精灵帧显示的图像。getOriginalSize()获取精灵帧原始尺寸。通过SpriteFrameCache类中SpriteFrame* getSpriteFrame(frameName)的获得。
  • SpriteFrameCache:精灵帧缓存类。存放了多个精灵帧,通过字典的方式存储单个精灵帧,key:精灵帧的名字,值: SpriteFrame。
  • AnimationFrame:动画帧信息类。存储的是对应的精灵帧信息。通过Animationconst Vector<AnimationFrame*>& getFrames()函数获得。该类中也可以通过函数SpriteFrame* getSpriteFrame()获取SpriteFrame对象
  • Animation:动画信息类。存储了所有的动画帧信息,一般通过create()或者createWithSpriteFrames()方法创建。
  • Animate: 动画处理类。真正完成动画表演的类。

添加精灵帧至缓存

把多张帧动画散图打成合图,生成plist、png文件,plist文件记载着每一帧在png中的位置信息。

    local plist, png = "plistname.plist", "pngname.png"
    cc.SpriteFrameCache:getInstance():addSpriteFrames(plist, png)

生成动画

使用精灵帧缓存生成帧数组创建动画.

-- 获取帧动画
local function getAnimation(time)
    local frameCount = 0
    local frames = {}
    while true do
        local key = string.format("effect_%02d.png", frameCount + 1)
        local frame = cc.SpriteFrameCache:getInstance():getSpriteFrame(key)
        if frame == nil then break end
        frameCount = frameCount + 1
        frames[frameCount] = frame
    end
    if #frames < 1 then return end 
    local animation = cc.Animation:createWithSpriteFrames(frames, time / frameCount) -- arg2:每一帧的时间
    return animation
end 

精灵执行动画

    -- 动作
    local actions = {}
    actions[#actions + 1] = cc.Animate:create(getAnimation(1)) -- 创建动画
    actions[#actions + 1] = cc.CallFunc:create(function()
        print("帧动画播放完毕")
    end)
    actions[#actions + 1] = cc.RemoveSelf:create()
    
    -- 依托精灵执行
    local sprite = cc.Sprite:create()
    sprite:addTo(self)
    sprite:stopAllActions()
    sprite:runAction(cc.Sequence:create(actions))

动画缓存

通常情况下,对于一个精灵动画,每次创建时都需要加载精灵帧,按顺序添加到数组,再创建对应动作类,这是一个非常烦琐的计算过程。对于使用频率高的动画,比如走路动画,将其加入缓存可以有效降低每次创建的巨大消耗。由于这个类的目的和缓存内容都非常简单直接,所以其接口也是最简单了的,如下所示:

AnimationCache:动画缓存类

static AnimationCache* getInstance(); // 全局共享的单例
void addAnimation(Animation *animation, const std::string& name); //添加一个动画到缓存
void addAnimationsWithFile(const std::string& plist); //添加动画文件到缓存
void removeAnimation(const std::string& name); //移除一个指定的动画
Animation* getAnimation(const std::string& name); //获得事先存入的动画

清理缓存

清理时先清理动画缓存,然后清理精灵帧缓存,最后是纹理缓存。按照引用层级由高到低,以保证释放引用有效。

void releaseCaches() { 
    AnimationCache::destroyInstance();
    SpriteFrameCache::getInstance()->removeUnusedSpriteFrames();
    TextureCache::getInstance()->removeUnuserdTextures(); 
}