quick-cocos2d-x游戏开发【8】——动画与动作

邴修远
2023-12-01

动画与动作,在quick中都有对其封装,所以我们还是来看一下吧。

总的来说,对于帧动画,quick封装的方法我们可以经常使用,这是非常方便的,下面直接上代码来直观感受下,

比如,14张帧图片,采用cocos2d-x lua的方法来写是这样的,

 local sp = display.newSprite("grossini_dance_01.png", display.cx, display.cy)
    self:addChild(sp)
    
    local animation = CCAnimation:create()
    local number, name
    for i = 1, 14 do
        if i < 10 then
            number = "0"..i
        else
            number = i
        end
        name = "grossini_dance_"..number..".png"
        animation:addSpriteFrameWithFileName(name)
    end

    animation:setDelayPerUnit(2.8 / 14.0)

    local action = CCAnimate:create(animation)
    sp:runAction(action)

需要将其每一帧添加到CCAnimation中,和C++使用是一样的,但是quick的用法就是这样子的了,

 display.addSpriteFramesWithFile("hero.plist", "hero.png") --添加帧缓存

    local sp = display.newSprite("#grossini_dance_01.png", display.cx, display.cy)
    self:addChild(sp)
    local frames = display.newFrames("grossini_dance_%02d.png", 1, 14)
    local animation = display.newAnimation(frames, 2.8/14.0)
    sp:playAnimationOnce(animation)

display.newFrames(pattern, begin, length, isReversed)的各个参数的意义是,

  • string pattern 模式字符串
  • integer begin 起始索引
  • integer length 长度
  • boolean isReversed 是否是递减索引
此外注意的是,newFrames里面的图片名称一定是帧缓存里面的图片名称,所以换句话说,我们之前需要将图片们用图片打包工具处理下,如果是采用多个单张图片的形式,肯定是不行的,可以想到,我们后期图片肯定都是采用图片打包工具处理的,所以quick就直接封装了这个方法。

不信的话,可以看下这个函数的源代码,

function display.newFrames(pattern, begin, length, isReversed)
    local frames = {}
    local step = 1
    local last = begin + length - 1
    if isReversed then
        last, begin = begin, last
        step = -1
    end

    for index = begin, last, step do
        local frameName = string.format(pattern, index)
        local frame = sharedSpriteFrameCache:spriteFrameByName(frameName)
        if not frame then
            printError("display.newFrames() - invalid frame, name %s", tostring(frameName))
            return
        end

        frames[#frames + 1] = frame
    end
    return frames
end


直接是调用spriteFrameByName函数。


对于播放动画,quick给Sprite精灵类提供了两个函数,

function Sprite:playAnimationOnce(animation, removeWhenFinished, onComplete, delay)
    return transition.playAnimationOnce(self, animation, removeWhenFinished, onComplete, delay)
end

function Sprite:playAnimationForever(animation, delay)
    return transition.playAnimationForever(self, animation, delay)
end

一个是播放动画一次,一个是永久播放动画。好用!


以上就是动画的用法,接下来我们再看关于动作的使用,

动作封装的类是transition,其中提供了这些函数,

transition.newEasing(action, easingName, more)
为图像创造效果
transition.execute(target, action, args)
执行一个动作效果
transition.rotateTo(target, args)
将显示对象旋转到指定角度,并返回 CCAction 动作对象。
transition.moveTo(target, args)
将显示对象移动到指定位置,并返回 CCAction 动作对象。
transition.fadeTo(target, args)
将显示对象的透明度改变为指定值,并返回 CCAction 动作对象。
transition.scaleTo(target, args)
将显示对象缩放到指定比例,并返回 CCAction 动作对象。
transition.sequence(actions)
创建一个动作序列对象。
transition.playAnimationOnce(target, animation, removeWhenFinished, onComplete, delay)
在显示对象上播放一次动画,并返回 CCAction 动作对象。

在我用来,我觉得像move,scale,fade这些单一的动作,我们用原生lua提供的那些就可以了,还容易被记住和使用,比如移动就使用CCMoveTo,还是挺好的。不过quick封装的个人觉得很不错的是,

transition.execute(target, action, args)

transition.sequence(actions)

这两个,为啥呢,接着看,


transition.execute() 是一个强大的工具,可以为原本单一的动作添加各种附加特性。

transition.execute() 的参数表格支持下列参数:

  • delay: 等待多长时间后开始执行动作
  • easing: 缓动效果的名字及可选的附加参数,效果名字不区分大小写
  • onComplete: 动作执行完成后要调用的函数
  • time: 执行动作需要的时间

transition.execute() 支持的缓动效果:

  • backIn
  • backInOut
  • backOut
  • bounce
  • bounceIn
  • bounceInOut
  • bounceOut
  • elastic, 附加参数默认为 0.3
  • elasticIn, 附加参数默认为 0.3
  • elasticInOut, 附加参数默认为 0.3
  • elasticOut, 附加参数默认为 0.3
  • exponentialIn, 附加参数默认为 1.0
  • exponentialInOut, 附加参数默认为 1.0
  • exponentialOut, 附加参数默认为 1.0
  • In, 附加参数默认为 1.0
  • InOut, 附加参数默认为 1.0
  • Out, 附加参数默认为 1.0
  • rateaction, 附加参数默认为 1.0
  • sineIn
  • sineInOut
  • sineOut
这个函数可以完成运动中的速度效果,以及CCCallFunc,CCDelayTime等功能,将其附加在一起,就不用写繁琐的函数嵌套和CCSequence了。廖大真是写到我的心坎里去了。像这样,

transition.execute(sprite, CCMoveTo:create(1.5, CCPoint(display.cx, display.cy)), {
    delay = 1.0,
    easing = "backout",
    onComplete = function()
        print("move completed")
    end,
})

transition.sequence也是一个方便的函数,如果要是以前,对于多个动作依次执行,咱们得这样,

 local move1  = CCMoveBy:create(1, ccp(250,0))
    local move2  = CCMoveBy:create(1, ccp(0,50))
    local array  = CCArray:createWithCapacity(2)
    array:addObject(move1)
    array:addObject(move2)
    local seq = CCSequence:create(array)

要把每个动作装在数组里面,然后才能创建一个CCSequence,而现在呢,

local sequence = transition.sequence({
        CCMoveBy:create(1, ccp(250,0)),
        CCMoveBy:create(1, ccp(0,50))
    })

直接和C++的写法一样,依次创建添加进去就可以了,非常方便~


以上就是全部内容了。

 类似资料: