• quick-cocos2d-x lua框架解析(一)对UI进行操作的UiUtil脚本


      最近一段时间接手了一个cocos游戏项目,由于我是U3D开发入门,所以花了一段时间来钻研cocos2d的使用与项目架构。与U3D相比,cocos2d的开发界面实在做的不咋地。不过在看过源码之后,源码跑起来还是比较稳健的,在此基础上做些修改也无不可。

      言归正传,先从底层工具入手,逐步解析整个项目。关于整个项目的结构,有时间我会专门记录一下。不过最近要修改客户端部分,所以优先以战斗逻辑为主。这里要记录的是UI底层部分的代码。

      先写下项目中自己定义的几个方法,其余方法均引自framework,就此不再详述(逐步深入,底层与应用层分离解析)。

    function cc.p(_x,_y)--传入参数_x,_y:如果_y为空,返回_x里的x、y值;否则返回原值
        if nil == _y then
             return { x = _x.x, y = _x.y }
        else
             return { x = _x, y = _y }
        end
    end
    -- load more library
    cc.ui = import(".ui.init")
    function cca.seq(acts)--序列发生器
       return cc.Sequence:create(acts)
    end

      这个脚本中包含了点击判断、颜色变化以及滚动等操作(引用了frameworks关于各种数据的定义,详见Cocos2dConstants脚本),具体代码如下:

    local Scheduler = require("framework.scheduler")--计时器的引用
    
    local UiUtil = {}--UI工具
    
    -- 判断是不是UIButton或者UIPushButton
    function UiUtil.isButton(node)
        if type(node.getClass) ~= "function" then
            return false
        end--如果没有挂载方法则什么都不做
    
        return node.getClass() == "UIButton" or node.getClass() == "UIPushButton"
    end
    
    -- 将全局坐标转换成基于node的本地坐标
    --在cocos中,node对象是场景图的基本元素
    function UiUtil.convertToNodeSpace(node, global_p, global_y)
        if type(global_p) == "number" then
            global_p = cc.p(global_p, global_y)
        end
    
        local point = node:convertToNodeSpace(global_p)--将Vec2转换为节点(本地)空间坐标。
    
        if UiUtil.isButton(node) then
            local content_size = node:getContentSize()--返回节点的未转换大小(逻辑点)
            if content_size.width == 0 or content_size.height == 0 then
                content_size = node:getCascadeBoundingBox().size
            end
    
            --求出本地坐标
            local anchor_point = node:getAnchorPoint()
            point.x = point.x + (anchor_point.x) * content_size.width
            point.y = point.y + (anchor_point.y) * content_size.height
        end
    
        return point
    end
    
    -- 根据点击位置检查结点是否被点击
    function UiUtil.checkNodeByPoint(node, global_p, global_y)
        local point = UiUtil.convertToNodeSpace(node, global_p, global_y)--将Vec2转换为节点(本地)空间坐标--#这里应该值得是相对于被点击区域的相对坐标
        local content_size = node:getContentSize()--返回节点的未转换大小(逻辑点)
    
        if content_size.width == 0 or content_size.height == 0 then
            content_size = node:getCascadeBoundingBox().size--求出边界大小
        end
    
        --如果在边界范围内则被点击,否则没有被点击
        if point.x >= 0 and point.x <= content_size.width and point.y >= 0 and point.y <= content_size.height then
            return true
        end
    
        return false
    end
    
    -- 根据点击位置找出被点击的子结点
    function UiUtil.findChildByPoint(parent, global_p, global_y)
        local ret = nil
    
        for _, child in ipairs(parent:getChildren()) do
            if UiUtil.checkNodeByPoint(child, global_p, global_y) then
                if ret == nil or child:getLocalZOrder() > ret:getLocalZOrder() then--获取本节点的深度顺序
                    ret = child
                end
            end
        end
    
        return ret
    end
    
    -- 按钮的长按回调:按钮、回调方法、首次点击时间、延迟回调时间
    -- 刚按下时回调一次,过first_delay秒后,每repeat_delay秒回调一次
    -- 当手指抬起,或者回调返回false时停止
    
    function UiUtil.buttonLongClick(button, callback, first_delay, repeat_delay)
        local handle = nil
        first_delay = first_delay or 0.5
        repeat_delay = repeat_delay or 0.1
    
        button:onButtonPressed(function(event)
            if not callback(1) then
                return
            end
    
            local count = 1
    
            handle = button:performWithDelay(function()
                handle = button:schedule(function(dt)
                    count = count + 1
    
                    if not callback(count) and handle then
                        button:stopAction(handle)
                        handle = nil
                    end
                end, repeat_delay)
            end, first_delay)
        end)
    
        button:onButtonRelease(function(event)
            if handle then
                button:stopAction(handle)
                handle = nil
            end
        end)
    end
    
    -- 用于非按钮组件监听clicked事件,会把符合条件的ended事件改成clicked事件
    -- params.click_only : boolean,只监听clicked事件
    -- params.distance_check :boolean,判定clicked事件时,是否检测松手时与按下时的距离
    -- params.move_check :boolean,判定clicked事件时,是否检测移动的次数
    function UiUtil.nodeTouchEvent(node, callback, params)
        params = params or {}
    
        local began_point
        local move_count
    
        node:setTouchEnabled(true)
        local handler = node:addNodeEventListener(cc.NODE_TOUCH_EVENT, function(event)
            if event.name == "began" then
                began_point = {x = event.x, y = event.y}
                move_count = 0
            elseif event.name == "moved" then
                move_count = move_count + 1
            elseif event.name == "ended" then
                if UiUtil.checkNodeByPoint(node, event) then
                    if (not params.distance_check or UiUtil.distance(began_point, event) < 15) and
                        (not params.move_check or move_count < 6) then
                        callback({name = "clicked", x = event.x, y = event.y})
    
                        return true
                    end
                end
            end
    
            if not params.click_only then
                callback(event)
            end
    
            return true
        end)
    
        return handler
    end
    
    -- 计算平面上两点间距离
    -- x1, y1, x2, y2 或 p1, p2
    function UiUtil.distance(a, b, c, d)
        local dx, dy
    
        if type(a) == "number" then
            dx = a - c
            dy = b - d
        else
            dx = a.x - b.x
            dy = a.y - b.y
        end
    
        return math.sqrt(dx * dx + dy * dy)
    end
    
    --移除节点的触摸事件监听
    function UiUtil.removeNodeTouchEvent(node, handler)
        if not node or not handler then
            return false
        end
    
        node:removeNodeEventListener(handler)
        return true
    end
    
    -- 创建添加右上角的返回按钮
    --ps:具体应用层,可以根据项目不同进行更改
    function UiUtil.createBackButton(parent)
        display.addSpriteFrames("res/ui/common/common0.plist", "res/ui/common/common0.png")--加载返回按钮的美术资源
    
        local button = cc.ui.UIPushButton.new()
        button:setButtonImage(cc.ui.UIPushButton.NORMAL, "#ty_fanhui.png")--正常状态
        button:setButtonImage(cc.ui.UIPushButton.PRESSED, "#ty_fanhui002.png")--点击状态
        button:setScale(1)--按钮缩放
        button:setPosition(parent:convertToNodeSpace(cc.p(display.width - 50, display.height - 50)))
        button:setLocalZOrder(20)
        button:setTouchSwallowEnabled(true)
        button:addTo(parent)
    
        return button
    end
    
    -- 把组件改成灰阶显示
    local program = nil
    function UiUtil.changeToGray(node)
        local vertDefaultSource = [[
            attribute vec4 a_position;
            attribute vec2 a_texCoord;
            attribute vec4 a_color;
    
            #ifdef GL_ES
                varying lowp vec4 v_fragmentColor;
                varying mediump vec2 v_texCoord;
            #else
                varying vec4 v_fragmentColor;
                varying vec2 v_texCoord;
            #endif
    
            void main() {
                gl_Position = CC_PMatrix * a_position;
                v_fragmentColor = a_color;
                v_texCoord = a_texCoord;
            }
        ]]
    
        local pszFragSource = [[
            #ifdef GL_ES
                precision mediump float;
            #endif
    
            varying vec4 v_fragmentColor;
            varying vec2 v_texCoord;
    
            void main(void) {
                vec4 c = texture2D(CC_Texture0, v_texCoord);
                gl_FragColor.xyz = vec3(0.4 * c.r + 0.4 * c.g + 0.4 * c.b);
                gl_FragColor.w = c.w;
            }
        ]]
    
        if not program then
            program = cc.GLProgram:createWithByteArrays(vertDefaultSource, pszFragSource)
    
            program:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION)
            program:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR)
            program:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_FLAG_TEX_COORDS)
            program:link()
            program:updateUniforms()
    
            -- program:retain()
        end
        node:setGLProgram(program)
    end
    
    --将组件及其包含的子组件全部置灰
    function UiUtil.changeToGrayRec(node)
        if node.setTextColor then
            return
        end
    
        UiUtil.changeToGray(node)
    
        for _, child in ipairs(node:getChildren()) do
            UiUtil.changeToGrayRec(child)
        end
    end
    
    -- 把组件改回彩色显示
    function UiUtil.changeToColor(node)
        node:setGLProgramState(cc.GLProgramState:getOrCreateWithGLProgram(cc.GLProgramCache:getInstance():getGLProgram("ShaderPositionTextureColor_noMVP")))
    end
    
    --将组件及其包含的子组件全部改变颜色
    function UiUtil.changeToColorRec(node)
        if node.setTextColor then
            return
        end
    
        UiUtil.changeToColor(node)
    
        for _, child in ipairs(node:getChildren()) do
            UiUtil.changeToColorRec(child)
        end
    end
    
    -- 把组件改成灰阶显示
    local spineToGrayprogram = nil
    function UiUtil.changeSpineToGray(node)
        local vertDefaultSource = [[
            attribute vec4 a_position;
            attribute vec2 a_texCoord;
            attribute vec4 a_color;
    
            #ifdef GL_ES
                varying lowp vec4 v_fragmentColor;
                varying mediump vec2 v_texCoord;
            #else
                varying vec4 v_fragmentColor;
                varying vec2 v_texCoord;
            #endif
    
            void main() {
                gl_Position = CC_MVPMatrix * a_position;
                v_fragmentColor = a_color;
                v_texCoord = a_texCoord;
            }
        ]]
    
        local pszFragSource = [[
            #ifdef GL_ES
                precision mediump float;
            #endif
    
            varying vec4 v_fragmentColor;
            varying vec2 v_texCoord;
    
            void main(void) {
                vec4 c = texture2D(CC_Texture0, v_texCoord);
                gl_FragColor.xyz = vec3(0.15 * c.r + 0.15 * c.g + 0.15 * c.b);
                gl_FragColor.w = c.w;
            }
        ]]
    
        if not spineToGrayprogram then
            spineToGrayprogram = cc.GLProgram:createWithByteArrays(vertDefaultSource, pszFragSource)
    
            spineToGrayprogram:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION)
            spineToGrayprogram:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR)
            spineToGrayprogram:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_FLAG_TEX_COORDS)
            spineToGrayprogram:link()
            spineToGrayprogram:updateUniforms()
    
            -- program:retain()
        end
        node:setGLProgram(spineToGrayprogram)
    end
    
    -- 把组件改成黑色显示
    local spineToBlackprogram = nil
    function UiUtil.changeSpineToBlack(node)
        local vertDefaultSource = [[
            attribute vec4 a_position;
            attribute vec2 a_texCoord;
            attribute vec4 a_color;
    
            #ifdef GL_ES
                varying lowp vec4 v_fragmentColor;
                varying mediump vec2 v_texCoord;
            #else
                varying vec4 v_fragmentColor;
                varying vec2 v_texCoord;
            #endif
    
            void main() {
                gl_Position = CC_MVPMatrix * a_position;
                v_fragmentColor = a_color;
                v_texCoord = a_texCoord;
            }
        ]]
    
        local pszFragSource = [[
            #ifdef GL_ES
                precision mediump float;
            #endif
    
            varying vec4 v_fragmentColor;
            varying vec2 v_texCoord;
    
            void main(void) {
                vec4 c = texture2D(CC_Texture0, v_texCoord);
                gl_FragColor.xyz = vec3(0.0 * c.r + 0.0 * c.g + 0.0 * c.b);
                gl_FragColor.w = c.w;
            }
        ]]
    
        if not spineToBlackprogram then
            spineToBlackprogram = cc.GLProgram:createWithByteArrays(vertDefaultSource, pszFragSource)
    
            spineToBlackprogram:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION)
            spineToBlackprogram:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR)
            spineToBlackprogram:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_FLAG_TEX_COORDS)
            spineToBlackprogram:link()
            spineToBlackprogram:updateUniforms()
    
            -- program:retain()
        end
        node:setGLProgram(spineToBlackprogram)
    end
    
    --褪色
    function UiUtil._fadeActionRec(node, action, cb)
        if not node or not action then
            return
        end
        if cb then
            node:runAction(cca.seq({action:clone(), cca.cb(cb)}))--序列发生器
        else
            node:runAction(action:clone())
        end
    
        for _, child in ipairs(node:getChildren()) do
            UiUtil._fadeActionRec(child, action)
        end
    end
    --全部褪色
    function UiUtil.fadeActionAll(node, time, to, cb)
        if not node then
            return
        end
    
        to = to or 0
        local action = cca.fadeTo(time, to)
        UiUtil._fadeActionRec(node, action, cb)
    end
    
    -- 把组件改成纯白色显示
    local spine_program = nil
    function UiUtil.changeSpineToWhite(spine_node)
        local vertDefaultSource = [[
            attribute vec4 a_position;
            attribute vec2 a_texCoord;
            attribute vec4 a_color;
    
            #ifdef GL_ES
                varying lowp vec4 v_fragmentColor;
                varying mediump vec2 v_texCoord;
            #else
                varying vec4 v_fragmentColor;
                varying vec2 v_texCoord;
            #endif
    
            void main() {
                gl_Position = CC_MVPMatrix * a_position;
                v_fragmentColor = a_color;
                v_texCoord = a_texCoord;
            }
        ]]
    
        local pszFragSource = [[
            #ifdef GL_ES
                precision mediump float;
            #endif
    
            varying vec4 v_fragmentColor;
            varying vec2 v_texCoord;
    
            void main(void) {
                vec4 c = texture2D(CC_Texture0, v_texCoord);
                gl_FragColor = vec4(c.r + c.g + c.b + c.a);
            }
        ]]
    
        if not spine_program then
            spine_program = cc.GLProgram:createWithByteArrays(vertDefaultSource, pszFragSource)
    
            spine_program:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION)
            spine_program:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR)
            spine_program:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_FLAG_TEX_COORDS)
            spine_program:link()
            spine_program:updateUniforms()
    
            -- spine_program:retain()
        end
        spine_node:setGLProgram(spine_program)
    end
    
    -- 把组件改成灰阶显示
    local spine_color_program = nil
    function UiUtil.changeSpineToColor(spine_node)
        local vertDefaultSource = [[
            attribute vec4 a_position;
            attribute vec2 a_texCoord;
            attribute vec4 a_color;
    
            #ifdef GL_ES
                varying lowp vec4 v_fragmentColor;
                varying mediump vec2 v_texCoord;
            #else
                varying vec4 v_fragmentColor;
                varying vec2 v_texCoord;
            #endif
    
            void main() {
                gl_Position = CC_MVPMatrix * a_position;
                v_fragmentColor = a_color;
                v_texCoord = a_texCoord;
            }
        ]]
    
        local pszFragSource = [[
            #ifdef GL_ES
                precision mediump float;
            #endif
    
            varying vec4 v_fragmentColor;
            varying vec2 v_texCoord;
    
            void main(void) {
                gl_FragColor = texture2D(CC_Texture0, v_texCoord);
            }
        ]]
    
        if not spine_color_program then
            spine_color_program = cc.GLProgram:createWithByteArrays(vertDefaultSource, pszFragSource)
    
            spine_color_program:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION)
            spine_color_program:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR)
            spine_color_program:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_FLAG_TEX_COORDS)
            spine_color_program:link()
            spine_color_program:updateUniforms()
    
            -- spine_color_program:retain()
        end
        spine_node:setGLProgram(spine_color_program)
    end
    
    
    -- 描边spine(黄色)
    local spine_outline_program = nil
    function UiUtil.outlineSpine(spine_node)
        local vertDefaultSource = [[
            attribute vec4 a_position;
            attribute vec2 a_texCoord;
            attribute vec4 a_color;
    
            #ifdef GL_ES
                varying lowp vec4 v_fragmentColor;
                varying mediump vec2 v_texCoord;
            #else
                varying vec4 v_fragmentColor;
                varying vec2 v_texCoord;
            #endif
    
            void main() {
                gl_Position = CC_MVPMatrix * a_position;
                v_fragmentColor = a_color;
                v_texCoord = a_texCoord;
            }
        ]]
    
        local pszFragSource = [[
            varying vec2 v_texCoord;
            varying vec4 v_fragmentColor;
    
            vec3 u_outlineColor = vec3(1,1,1);
            float u_threshold = 0.12;
            float u_radius = 0.005;
    
            void main()
            {
                float radius = u_radius;
                vec4 accum = vec4(0.0);
                vec4 normal = vec4(0.0);
    
                normal = texture2D(CC_Texture0, vec2(v_texCoord.x, v_texCoord.y));
    
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x - radius, v_texCoord.y - radius));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x + radius, v_texCoord.y - radius));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x + radius, v_texCoord.y + radius));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x - radius, v_texCoord.y + radius));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x - radius, v_texCoord.y));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x + radius, v_texCoord.y));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x, v_texCoord.y - radius));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x, v_texCoord.y + radius));
    
                accum *= u_threshold;
                accum.rgb =  u_outlineColor * accum.a;
                accum.a = normal.a;
    
                normal = ( accum * (1.0 - normal.a)) + (normal * normal.a);
    
                gl_FragColor = v_fragmentColor * normal;
            }
        ]]
    
        if not spine_outline_program then
            spine_outline_program = cc.GLProgram:createWithByteArrays(vertDefaultSource, pszFragSource)
    
            spine_outline_program:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION)
            spine_outline_program:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR)
            spine_outline_program:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_FLAG_TEX_COORDS)
            spine_outline_program:link()
            spine_outline_program:updateUniforms()
    
            -- spine_outline_program:retain()
        end
        spine_node:setGLProgram(spine_outline_program)
    end
    
    local outline_program = nil
    function UiUtil.outline(node)
        local vertDefaultSource = [[
            attribute vec4 a_position;
            attribute vec2 a_texCoord;
            attribute vec4 a_color;
    
            #ifdef GL_ES
                varying lowp vec4 v_fragmentColor;
                varying mediump vec2 v_texCoord;
            #else
                varying vec4 v_fragmentColor;
                varying vec2 v_texCoord;
            #endif
    
            void main() {
                gl_Position = CC_PMatrix * a_position;
                v_fragmentColor = a_color;
                v_texCoord = a_texCoord;
            }
        ]]
    
        local pszFragSource = [[
            varying vec2 v_texCoord;
            varying vec4 v_fragmentColor;
    
            vec3 u_outlineColor = vec3(1,1,1);
            float u_threshold = 0.12;
            float u_radius = 0.01;
    
            void main()
            {
                float radius = u_radius;
                vec4 accum = vec4(0.0);
                vec4 normal = vec4(0.0);
    
                normal = texture2D(CC_Texture0, vec2(v_texCoord.x, v_texCoord.y));
    
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x - radius, v_texCoord.y - radius));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x + radius, v_texCoord.y - radius));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x + radius, v_texCoord.y + radius));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x - radius, v_texCoord.y + radius));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x - radius, v_texCoord.y));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x + radius, v_texCoord.y));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x, v_texCoord.y - radius));
                accum += texture2D(CC_Texture0, vec2(v_texCoord.x, v_texCoord.y + radius));
    
                accum *= u_threshold;
                accum.rgb =  u_outlineColor * accum.a;
                accum.a = normal.a;
    
                normal = ( accum * (1.0 - normal.a)) + (normal * normal.a);
    
                gl_FragColor = v_fragmentColor * normal;
            }
        ]]
    
        if not outline_program then
            outline_program = cc.GLProgram:createWithByteArrays(vertDefaultSource, pszFragSource)
    
            outline_program:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION)
            outline_program:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR)
            outline_program:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_FLAG_TEX_COORDS)
            outline_program:link()
            outline_program:updateUniforms()
    
            -- outline_program:retain()
        end
        node:setGLProgram(outline_program)
    end
    
    --总要
    function UiUtil.outlineRec(node)
        UiUtil.outline(node)
    
        for _, child in ipairs(node:getChildren()) do
            UiUtil.outline(child)
        end
    end
    
    local NodeRec
    function NodeRec(node, fun_name)
        if not node[fun_name] then
            _dump("node没有方法"..fun_name)
            return
        end
    
        node[fun_name](node)
        for _, child in ipairs(node:getChildren()) do
            NodeRec(child, fun_name)
        end
    end
    
    function UiUtil.activeNodeRec(node,  bflag)
        local fun_name = ""
        if bflag then
            fun_name = "resume"--摘要
        else
            fun_name = "pause"--暂停
        end
    
        NodeRec(node, fun_name)
    end
    --spine变色(项目中没使用)
    function UiUtil.changeToColor2(node)
        node:setGLProgramState(cc.GLProgramState:getOrCreateWithGLProgram(cc.GLProgramCache:getInstance():getGLProgram("ShaderPositionTextureColor")))
    end
    
    -- 滚动到最上边
    -- view:竖向滚动的UIScrollView或UIListView
    function UiUtil.scrollToTop(view)
        local view_rect = view:getViewRect()
        view:scrollTo(view_rect.x, view_rect.y - view:getScrollNode():getContentSize().height + view_rect.height)
    end
    
    -- 滚动到最下边
    -- view:竖向滚动的UIScrollView或UIListView
    function UiUtil.scrollToBottom(view)
        local view_rect = view:getViewRect()
        view:scrollTo(view_rect.x, view_rect.y)
    end
    
    -- 滚动到最左边
    -- view:横向滚动的UIScrollView或UIListView
    function UiUtil.scrollToLeft(view)
        local view_rect = view:getViewRect()
        view:scrollTo(view_rect.x, view_rect.y)
    end
    
    -- 滚动到最右边
    -- view:横向滚动的UIScrollView或UIListView
    function UiUtil.scrollToRight(view)
        local view_rect = view:getViewRect()
        view:scrollTo(view_rect.x - view:getScrollNode():getContentSize().width + view_rect.width, view_rect.y)
    end
    
    -- UIScrollView滚动指定距离
    function UiUtil.scrollBy(scroll_view, x, y, time, callback)
        x = x or 0
        y = y or 0
    
        if not time or time <= 0 then
            local px, py = scroll_view:getScrollNode():getPosition()
            scroll_view:scrollTo(px + x, py + y)
            if callback then
                callback()
            end
        else
            transition.moveBy(scroll_view:getScrollNode(), {x = x, y = y, time = time, onComplete = callback})
        end
    end
    
    -- UIScrollView滚动到指定位置
    function UiUtil.scrollTo(scroll_view, x, y, time, callback)
        local px, py = scroll_view:getScrollNode():getPosition()
        x = x or px
        y = y or py
    
        if not time or time <= 0 then
            scroll_view:scrollTo(x, y)
            if callback then
                callback()
            end
        else
            transition.moveTo(scroll_view:getScrollNode(), {x = x, y = y, time = time, onComplete = callback})
        end
    end
    
    --根据横竖的格子数,格子的index,返回格子所在的行数i和列数j
    function UiUtil.getGridPos(width, height, index)
        if not (width > 0 and height > 0 and index > 0) then
            print("error info")
            return nil, nil
        end
    
        local i, j = index % width, math.ceil(index / width)
    
        if i == 0 then
            i = width
        end
    
        return i, j
    end
    
    function UiUtil.getLabel(text, size, color, outline_color, outline, dimensions, align, valign)
        local text = text or ""
        local size = size or 20
        local color = color or cc.c3b(0xff, 0xff, 0xff)
        local align = align or cc.TEXT_ALIGNMENT_CENTER  --cc.TEXT_ALIGNMENT_LEFT cc.TEXT_ALIGNMENT_RIGHT = 0x2
        local valign = valign or cc.VERTICAL_TEXT_ALIGNMENT_CENTER
    
        local label_params = {
            text = text,
            font = "ms_yahei",
            size = size,
            color = color,
            align = align,
            valign = valign,
            dimensions = dimensions,--cc.size(400, 200)
        }
        local label = display.newTTFLabel(label_params)
        if outline_color then
            label:enableOutline(outline_color, outline or 2) --cc.c4b(0x28,0x2d,0x38,255)
        end
        return label
    end
    --变化
    function UiUtil.setLabel(label, str, color, outline_color, outline)
        if not label then
            return
        end
        if str then
            label:setString(str)
        end
        if color then
            label:setTextColor(color)
        end
        if outline_color then
            label:enableOutline(outline_color, outline or 2)
        end
    end
    --格子变化
    function UiUtil.runTask_(node)
        local task = node.task_queue[1]
        if not task then
            node.task_running = false
            return
        end
    
        table.remove(node.task_queue, 1)
        node.task_running = true
    
        node:performWithDelay(function()
            task()
    
            UiUtil.runTask_(node)
        end, 0.01)
    end
    --改变一个格子
    function UiUtil.runTaskOnNode(node, task)
        if not node.task_queue then
            node.task_queue = {}
        end
    
        table.insert(node.task_queue, task)
    
        if not node.task_running then
            UiUtil.runTask_(node)
        end
    end
    --用于新手引导的开关
    function UiUtil.setTouchSwallowEnabledRec(node, enabled)
        node:setTouchSwallowEnabled(enabled)
    
        local children = node:getChildren()
        for _, v in ipairs(children) do
            UiUtil.setTouchSwallowEnabledRec(v, enabled)
        end
    end
    
    return UiUtil

      脚本里面的原理也可以用于其他代码,如果是framework核心的cocos项目,改一改直接就可以使用。

      工作后看了不少代码,发现原理很多都相似,暂时写到这里,继续啃游戏逻辑去了。

  • 相关阅读:
    visio 2019 激活方法
    sftp 多用户安装与配置
    CentOS configuration uses the SFTP server
    esxi命令行强行关闭虚拟机
    esxi 版本升级命令
    存储分析 开源重复数据删除技术崭露头角
    最简单-转换MBR为GPT
    CentOS 7 搭建本地YUM仓库,并定期同步阿里云源
    uml建模工具介绍
    C/C++中extern关键字详解
  • 原文地址:https://www.cnblogs.com/yangyadong66/p/9474982.html
Copyright © 2020-2023  润新知