This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English

逐帧动画

逐帧动画就是由一些列静态图片轮流显示生成的动画. 这种技术类似于老式翻页动画 (详见 http://en.wikipedia.org/wiki/Traditional_animation). 由于每帧的独立性使得这种技术很自由. 但是每帧一张图片会很耗费内存. 相似图片越多动画过渡越平滑同时也带来了巨大的工作量. Defold 逐帧动画使用来自于 图集, 或者 瓷砖图源 里水平排列的图片.

Animation sheet Run loop

播放逐帧动画

Sprite 和 GUI 方块节点可以用来播放逐帧动画而且可以在运行时进行控制.

Sprites
通过调用 sprite.play_flipbook() 函数播放逐帧动画. 示例见下文.
GUI 方块节点
通过调用 gui.play_flipbook() 函数播放逐帧动画. 示例见下文.

ping-pong 播放模式把动画从第一帧播放到最后一帧再反向播放到 第二帧 , 而不是第一帧. 这样便于连续播放的衔接.

Sprite 示例

假设你的游戏有个 “dodge” 功能, 按下指定的键主角就进行闪避动作. 为此你建立了四组动画:

“idle”
主角待机的循环动画.
“dodge_idle”
主角闪避动作的循环动画.
“start_dodge”
主角从站立姿态到闪避动作的一次性动画.
“stop_dodge”
主角从闪避动作到站立姿态的一次性动画.

逻辑代码如下:


local function play_idle_animation(self)
    if self.dodge then
        sprite.play_flipbook("#sprite", hash("dodge_idle"))
    else
        sprite.play_flipbook("#sprite", hash("idle"))
    end
end

function on_input(self, action_id, action)
    -- "dodge" 就是输入动作
    if action_id == hash("dodge") then
        if action.pressed then
            sprite.play_flipbook("#sprite", hash("start_dodge"), play_idle_animation)
            -- 记录闪避动作已开始
            self.dodge = true
        elseif action.released then
            sprite.play_flipbook("#sprite", hash("stop_dodge"), play_idle_animation)
            -- 记录闪避动作完成
            self.dodge = false
        end
    end
end

GUI 方块节点示例

给节点选择图片或者动画时, 实际上也同时指定了图片来源 (图集或者瓷砖图源) 以及默认动画. 节点图源是静态的, 但是当前播放的动画是可以在运行时指定的. 静态图片被视作单帧动画, 所以运行时切换图片相当于播放另一个动画:

function init(self)
    local character_node = gui.get_node("character")
    -- 新动画/图片播放时
    -- 节点图源要存在默认动画.
    gui.play_flipbook(character_node, "jump_left", flipbook_done)
end

播放完成回调函数

动画函数 (sprite.play_flipbook()gui.play_flipbook()) 可以在最后一个参数上传入Lua回调函数. 当动画播放完成时会调用这个函数. 对于循环动画和用 go.cancel_animations() 手动取消播放的动画, 不会调用回调函数. 动画播放完成的回调函数里可以发送消息或者继续播放其他动画. 例如:

local function flipbook_done(self)
    msg.post("#", "jump_completed")
end

function init(self)
    sprite.play_flipbook("#character", "jump_left", flipbook_done)
end
local function flipbook_done(self)
    msg.post("#", "jump_completed")
end

function init(self)
    gui.play_flipbook(gui.get_node("character"), "jump_left", flipbook_done)
end