zoukankan      html  css  js  c++  java
  • Bolt 动画

    引擎内置的 6 种动画
    --PosChangeAnimation 平移
    local ani = XLGetObject("Xunlei.UIEngine.AnimationFactory"):CreateAnimation("PosChangeAnimation")
    ani:BindObj(imageObj)
    ani:SetTotalTime(5000)
    ani:SetLoop(true)
    ani:SetKeyFramePos(100,0,200,0)
    imageObj:GetOwner():AddAnimation(ani)
    ani:Resume()
    
    --AngleChangeAnimation 旋转
    local ani = XLGetObject("Xunlei.UIEngine.AnimationFactory"):CreateAnimation("AngleChangeAnimation")
    ani:BindObj(imageObj)
    ani:SetKeyFrameAngle(0,0,0,0,0,360)
    ani:SetTotalTime(5000)
    ani:SetLoop(true)
    ani:SetBlendMode("AntiAlias")
    imageObj:GetOwner():AddAnimation(ani)
    ani:Resume()
    
    --AlphaChangeAnimation 透明度
    local ani = XLGetObject("Xunlei.UIEngine.AnimationFactory"):CreateAnimation("AlphaChangeAnimation")
    ani:BindRenderObj(imageObj)
    ani:SetTotalTime(2000)
    ani:SetKeyFrameAlpha(255,0)
    imageObj:GetOwner():AddAnimation(ani)
    ani:Resume()
    
    --SeqFrameAnimation 序列帧 
    local ani = XLGetObject("Xunlei.UIEngine.AnimationFactory"):CreateAnimation("SeqFrameAnimation")
    ani:BindImageObj(imageObj)
    ani:SetTotalTime(2000)
    ani:SetLoop(true)
    ani:SetResID("ImageSeq.BoltTest.SeqAni")
    imageObj:GetOwner():AddAnimation(ani)
    ani:Resume()
    
    --TurnObjectAnimation 对象1旋转到对象2
    local imageObj2 = ctrlObj:GetControlObject("TestAni2.Texture")
    local ani = XLGetObject("Xunlei.UIEngine.AnimationFactory"):CreateAnimation("TurnObjectAnimation")
    ani:BindRenderObj(imageObj1,imageObj2)
    ani:SetFlag("RoundY")
    ani:SetTotalTime("500")
    imageObj1:GetOwner():AddAnimation(ani)
    ani:Resume()
    
    --MaskChangeAnimation MaskObject 位置改变
    local maskObj = ctrlObj:GetControlObject("MaskAni.Mask")
    local uiObject = ctrlObj:GetControlObject("MaskAniBkg.Texture")
    local ani = XLGetObject("Xunlei.UIEngine.AnimationFactory"):CreateAnimation("MaskChangeAnimation")
    ani:BindMaskObj(maskObj)
    ani:SetMaskKeyFrame(0,0,80,80,0,-80,80,80)
    ani:SetLoop(true)
    ani:SetTotalTime(1000)
    maskObj:GetOwner():AddAnimation(ani)
    ani:Resume()
    
    MaskObject 的使用方法参考相关文档;
    注意这里只调用了 BindMaskObj 而没有调用 BindTargetObj ,不知道为啥调用了 BindTargetObj 之后动画并不会被执行
    注意:不知道为啥旋转动画不能在OnInitControl里面直接使用,需要用AsynCall调用才行:
    function OnInitControl(ctrlObj)
        local imageObj = ctrlObj:GetControlObject("TestAni.Image")
        
        AsynCall(function()        -- 异步调用
            -- AngleChangeAnimation 旋转
            local rotateAni = XLGetObject("Xunlei.UIEngine.AnimationFactory"):CreateAnimation("AngleChangeAnimation")
            rotateAni:BindObj(imageObj)
            rotateAni:SetKeyFrameAngle(0,0,0,0,0,360)
            rotateAni:SetTotalTime(5000)
            rotateAni:SetLoop(false)
            rotateAni:SetBlendMode("AntiAlias")
            imageObj:GetOwner():AddAnimation(rotateAni)
            rotateAni:Resume()
        end)
    end
    
    
    
    自定义动画:
    在 xml 文件里定义动画模版:
    <animation_def class="BoltTest.ani">
        <method_def>
            <Action file="MainWnd.xml.lua" func="BoltTestAni_Action"/>
            <BindObj file="MainWnd.xml.lua" func="BoltTestAni_BindObj"/>
            <GetBindObj file="MainWnd.xml.lua" func="BoltTestAni_GetBindObj" />
        </method_def>
    </animation_def>
    
    在 lua 文件里使用动画:
    function BoltTestAni_Action(aniSelf)
        local attr = aniSelf:GetAttribute()
        local bindObj = attr.BindObj
        if bindObj == nil then
            return
        end
        
        local totalTime = aniSelf:GetTotalTime()
        local runningTime = aniSelf:GetRuningTime()
        
        --[[ 按时间缩小
        local progress = (totalTime - runningTime) / totalTime
        if progress < 0 then
            progress = 0
        end
        local l,t,r,b = bindObj:GetObjPos()
        bindObj:SetObjPos(l,t,r,t+(b-t)*progress)
        --]]
        
        -- 按指定间隔切换图片
        local frameTime = 1000
        local progress = runningTime / frameTime + 1
        if progress > 5 then
            progress = 5
        elseif progress < 1 then
            progress = 1
        end
        progress = math.floor(progress)
        bindObj:SetResID("Bitmap.BoltTest.SeqAni"..progress)
    end
    function BoltTestAni_BindObj(aniSelf, obj)
        local attr = aniSelf:GetAttribute()
        attr.BindObj = obj
    end
    function BoltTestAni_GetBindObj(aniSelf)
        local attr = aniSelf:GetAttribute()
        return attr.BindObj
    end
    
    注意:XLUE 每隔 1/30 秒刷新一次界面,每次刷新时改变对象的状态,这是自定义动画的基本原理;
    Action 方法每隔 1/30 秒调用一次;
    BindObj 方法里通过 attr 表来保存要渲染的对象;
    GetRuningTime 方法获取动画的运行时间,因为是每隔 1/30 秒调用一次 Action 方法,所以 GetRuningTime 也是每隔 1/30 递增
    
    
    动画的状态改变事件:
    -- state: 0 动画未绑定对象;1 动画准备就绪;2 动画正在执行;3 动画暂停; 4 动画结束
    ani:AttachListener(true, function(aniSelf, oldState, newState)
        -- TODO
    end)
    注意这里,如果设定动画 SetLoop(true) state 将在 24 之间转换;
    对一个动画进行 Stop,state 变为 4 而不是 3;也就是动画结束而不是动画暂停;
    对一个动画进行 Stop,再调用 resume 并不能够使暂停的动画重新开始;
    对一个动画进行 Stop,该动画实例即失效,需要重新创建该动画才能使动画重新运行
    
    
    同时执行多个动画:
    将多个动画对象绑定到同一个 UIObject 上即可:
    -- PosChangeAnimation 平移
    local ani = XLGetObject("Xunlei.UIEngine.AnimationFactory"):CreateAnimation("PosChangeAnimation")
    ani:BindObj(imageObj)
    ani:SetTotalTime(5000)
    ani:SetLoop(false)
    ani:SetKeyFramePos(100,0,200,0)
    imageObj:GetOwner():AddAnimation(ani)
    ani:Resume()
    
    --SeqFrameAnimation 序列帧 
    local ani = XLGetObject("Xunlei.UIEngine.AnimationFactory"):CreateAnimation("SeqFrameAnimation")
    ani:BindImageObj(imageObj)
    ani:SetTotalTime(2000)
    ani:SetLoop(true)
    ani:SetResID("ImageSeq.BoltTest.SeqAni")
    imageObj:GetOwner():AddAnimation(ani)
    ani:Resume()
    注意这里,不知道为啥 AngleChangeAnimation 旋转动画跟 SeqFrameAnimation 序列帧动画不能一起用;
    
    
    执行动画序列:
    local function StartAnimSequence(onFinish, ...)
        local function StartAnim(aniIndex)
            if arg[aniIndex] == nil then
                onFinish()
                return
            end
            arg[aniIndex]:AttachListener(true, function(aniSelf, oldState, newState)
                if newState == 4 then
                    StartAnim(aniIndex + 1)
                end
            end)
            arg[aniIndex]:Resume()
        end
        StartAnim(1)
    end
    StartAnimSequence(function() return end, posAni, rotateAni)
    尝试用这种方法封装一个执行动画序列的方法;发现不行,不知道为啥;
    
    
    动画曲线: 
    在资源 xml 里定义 curve 资源,可使用 CurveTool 工具来定义:
    <curve id="Curve.BoltTest.MyAni" type="bspline">
        <controlpoint  tp="0.000000" sp="0.000000"/>
        <controlpoint  tp="0.854396" sp="0.025281"/>
        <controlpoint  tp="0.859890" sp="0.977528"/>
        <controlpoint  tp="0.997253" sp="1.000000"/>
    </curve>
    在自定义动画里通过 Curve:GetProgress(tp) 传入一个时间,获取对应的进度:
    local curve = aniSelf:GetCurve()
    local tp = runningTime / totalTime
    local progress = curve:GetProgress(tp)
    利用这个 progress 来设定进度即可
  • 相关阅读:
    适用于ASP.NET的留言本(翻译)
    大足石刻一日游
    Zonet 宽带路由器eMule端口映射设置
    在公式编辑器中使用键盘
    TAU G2的错误信息:TSC0134: Transition must end with stop, nextstate or join action
    Sony DV的CCD也是有问题的
    使用UltraEdit实现从UNIX文件到DOS文件的批量转换
    在PowerPoint中改变公式编辑器的颜色
    如何在Visual Studio.NET 2003下编译ANTLR 2.77
    如何修复修复损坏的TAU G2的.u2文件
  • 原文地址:https://www.cnblogs.com/zuibunan/p/3606295.html
Copyright © 2011-2022 走看看