quick-cocos2d-x tips

quick-cocos2d-x tips,第1张

概述原文请猛戳: http://galoisplusplus.coding.... 承接上一篇,这篇主要谈谈本渣在quickx用的一些脚本或自己折腾的一些定制,本文也将不时更新。 如无特殊说明,相关函数放在一个MyPackage的lua global table中: MyPackage = MyPackage or {} UI组件 滚动列表相关 --[[--Refresh UIListView at

原文请猛戳:
http://galoisplusplus.coding....

承接上一篇,这篇主要谈谈本渣在quickx用的一些脚本或自己折腾的一些定制,本文也将不时更新。

如无特殊说明,相关函数放在一个MyPackage的lua global table中:

MyPackage = MyPackage or {}
UI组件 滚动列表相关
--[[--Refresh UIListVIEw at the current postion.NOTE: only needed in async mode]]function MyPackage.refreshUIListVIEw(ListVIEw)    if not ListVIEw.bAsyncLoad then        ListVIEw:reload()        return    end    if #ListVIEw.items_ <= 0 then        ListVIEw:reload()        return    end    local originPos = MyPackage.getoriginPosOfUIListVIEw(ListVIEw)    -- index of the prevIoUs beginning item    local beginIDx = ListVIEw.items_[1].IDx_    ListVIEw:removeAllitems()    ListVIEw.container:setposition(0,0)    ListVIEw.container:setContentSize(cc.size(0,0))    MyPackage.drawUIListVIEwFromIDx(ListVIEw,beginIDx,originPos.x,originPos.y)end--[[--NOTE: only needed in async mode]]function MyPackage.getoriginPosOfUIListVIEw(ListVIEw)    if not ListVIEw.bAsyncLoad then        return    end    local getContainerCascadeBoundingBox = function (ListVIEw)        local boundingBox        for i,item in ipairs(ListVIEw.items_) do            local w,h = item:getItemSize()            local x,y = item:getposition()            local anchor = item:getAnchorPoint()            x = x - anchor.x * w            y = y - anchor.y * h            if boundingBox then                boundingBox = cc.rectUnion(boundingBox,cc.rect(x,y,w,h))            else                boundingBox = cc.rect(x,h)            end        end        local point = ListVIEw.container:convertToWorldspace(cc.p(boundingBox.x,boundingBox.y))        boundingBox.x = point.x        boundingBox.y = point.y        return boundingBox    end    local cascadeBound = getContainerCascadeBoundingBox(ListVIEw)--    local cascadeBound = ListVIEw.scrollNode:getCascadeBoundingBox()    local localPos = ListVIEw:convertToNodeSpace(cc.p(cascadeBound.x,cascadeBound.y))    local originPosX = 0    local originPosY = 0    if cc.ui.UIScrollVIEw.DIRECTION_VERTICAL == ListVIEw.direction then        -- ahead part of vIEw        originPosY = localPos.y + cascadeBound.height - ListVIEw.vIEwRect_.y - ListVIEw.vIEwRect_.height    else        -- left part of vIEw        originPosX = - ListVIEw.vIEwRect_.x + localPos.x    end    return cc.p(originPosX,originPosY)end--[[--Draw UIListVIEw from the `beginIDx`th item at position (`originPosX`,`originPosY`).NOTE: only needed in async mode]]function MyPackage.drawUIListVIEwFromIDx(ListVIEw,originPosX,originPosY)    if not ListVIEw.bAsyncLoad then        ListVIEw:reload()        return    end    ListVIEw:removeAllitems()    ListVIEw.container:setposition(0,0))    local beginIDx = beginIDx or 1    local originPosX = originPosX or 0    local originPosY = originPosY or 0    local count = ListVIEw.delegate_[cc.ui.UIListVIEw.DELEGATE](ListVIEw,cc.ui.UIListVIEw.COUNT_TAG)    ListVIEw.items_ = {}    local itemW,itemH = 0,0    local item    local containerW,containerH = 0,0    for i = beginIDx,count do        item,itemW,itemH = ListVIEw:loadOneItem_(cc.p(originPosX,originPosY),i)        if cc.ui.UIScrollVIEw.DIRECTION_VERTICAL == ListVIEw.direction then            originPosY = originPosY - itemH            containerH = containerH + itemH        else            originPosX = originPosX + itemW            containerW = containerW + itemW        end        if containerW > ListVIEw.vIEwRect_.wIDth + ListVIEw.redundancyVIEwVal            or containerH > ListVIEw.vIEwRect_.height + ListVIEw.redundancyVIEwVal then            break        end    end    if cc.ui.UIScrollVIEw.DIRECTION_VERTICAL == ListVIEw.direction then        ListVIEw.container:setposition(ListVIEw.vIEwRect_.x,ListVIEw.vIEwRect_.y + ListVIEw.vIEwRect_.height)    else        ListVIEw.container:setposition(ListVIEw.vIEwRect_.x,ListVIEw.vIEwRect_.y)    end    ListVIEw:increaSEOrReduceItem_()endfunction MyPackage.elasticMoveUIScrollVIEw(scrollVIEw,scrollToBottom,scrollToRight)    local cascadeBound = scrollVIEw:getScrollNodeRect()    local disX,disY = 0,0    local vIEwRect = scrollVIEw:getVIEwRectInWorldspace()    if cascadeBound.wIDth < vIEwRect.wIDth then        if scrollToRight then            disX = vIEwRect.x + vIEwRect.wIDth - cascadeBound.x - cascadeBound.wIDth        else            disX = vIEwRect.x - cascadeBound.x        end    else        if cascadeBound.x > vIEwRect.x then            disX = vIEwRect.x - cascadeBound.x        elseif cascadeBound.x + cascadeBound.wIDth < vIEwRect.x + vIEwRect.wIDth then            disX = vIEwRect.x + vIEwRect.wIDth - cascadeBound.x - cascadeBound.wIDth        end    end    if cascadeBound.height < vIEwRect.height then        if scrollToBottom then            disY = vIEwRect.y - cascadeBound.y        else            disY = vIEwRect.y + vIEwRect.height - cascadeBound.y - cascadeBound.height        end    else        if cascadeBound.y > vIEwRect.y then            disY = vIEwRect.y - cascadeBound.y        elseif cascadeBound.y + cascadeBound.height < vIEwRect.y + vIEwRect.height then            disY = vIEwRect.y + vIEwRect.height - cascadeBound.y - cascadeBound.height        end    end    if 0 == disX and 0 == disY then        return    end    local posX,posY = scrollVIEw.scrollNode:getposition()    scrollVIEw.position_ = cc.p(posX + disX,posY + disY)    scrollVIEw.scrollNode:setposition(scrollVIEw.position_)end

更新:以上改动已挪到yszheda/quickx-extensions的UIScrollVIEw或UIListVIEw中。

lua语言相关 bool转数字
function MyPackage.bool2number(bool)    return bool and 1 or 0end
table相关
function MyPackage.removeValueFromArray(array,value)    local IDx    for i,v in ipairs(array) do        if v == value then            IDx = i            break        end    end    if IDx then        table.remove(array,IDx)    endendfunction MyPackage.hasValueInArray(array,value)    local hasValue = false    for i,v in ipairs(array) do        if v == value then            hasValue = true            break        end    end    return hasValueend
UTF8字符串

cocos2d-x的label默认为UTF8编码,一般场景下主要需要以下两个功能:

字符串长度

截取子串

原先本渣用cocos2d-x时写了个C++函数来求长度:

long long utf8StringSize(const std::string& str){    char* chararray = new char[str.length() + 1];    strcpy(chararray,str.c_str());    char* s = chararray;    /*-----------------------------------------------------------------------------     *  References: http://stackoverflow.com/questions/4063146/getting-the-actual-length-of-a-utf-8-encoded-stdstring     *-----------------------------------------------------------------------------*/    long long len = 0;    while (*s) len += (*s++ & 0xc0) != 0x80;    delete [] chararray;    return len;}

cocos2d-x Helper也提供了接口来做字符串截取:

static std::string getSubStringOfUTF8String(const std::string& str,std::string::size_type start,std::string::size_type length);

在lua方面,quickx已经提供string.utf8len来求字符串长度,本渣仿照其实现写了个截取子串的函数:

function MyPackage.utf8str(str,start,num)    local function utf8CharSize(char)        local size = 0        local arr = {0,0xc0,0xe0,0xf0,0xf8,0xfc}        local size = #arr        while arr[size] do            if char >= arr[size] then                break            end            size = size - 1        end        return size    end    local startIDx = 1    while start > 1 do        local char = string.byte(str,startIDx)        startIDx = startIDx + utf8CharSize(char)        start = start - 1    end    local endIDx = startIDx    while num > 0 do        if endIDx > #str then            endIDx = #str            break        end        local char = string.byte(str,endIDx)        endIDx = endIDx + utf8CharSize(char)        num = num - 1    end    return str:sub(startIDx,endIDx - 1)end

不过目前lua5.3已经有UTF8库,可以不用自行造轮子了。另外,关于其他UTF8相关的lua问题可以参考Lua Unicode。

其他Helper Functions 更新vIEw的callbackWrapper

我们经常碰到如下的情景:
游戏向后端请求数据,在拿到数据之后执行某个callback去更新某个vIEw。
这种网络请求通常是异步的,如果所请求的数据回来时相关的vIEw被释放,则执行 *** 作该vIEw的callback会导致问题(例如访问非法内存地址)。
这时候我们可以用tolua.isnull来判断相关的vIEw对象是否被释放。
由于每个这种类型的callback都有必要加上这样的guard code,所以本渣干脆做了如下的接口:

function MyPackage.callbackWrapper(vIEws,callback)    return function(...)        for _,vIEw in pairs(vIEws) do            if tolua.isnull(vIEw) then                return            end        end        if callback ~= nil then            callback(...)        end    endend
拿到一个node九个端点的坐标
--[[--get the nine positions of a node (the following variables are defined in display.lua of quickx):display.CENTERdisplay.left_topdisplay.CENTER_topdisplay.RIGHT_topdisplay.CENTER_leftdisplay.CENTER_RIGHTdisplay.BottOM_leftdisplay.BottOM_RIGHTdisplay.BottOM_CENTER]]function MyPackage.getpositionOfNode(node,alignType)    if not node or tolua.isnull(node) then        return    end    local size = node:getContentSize()    if size.wIDth == 0 and size.height == 0 then        size = node:getCascadeBoundingBox()    end    local pos = cc.p(node:getposition())    local anchorPoint = cc.p(node:getAnchorPoint())    if alignType == display.left_top or        alignType == display.left_CENTER or        alignType == display.left_BottOM then        pos.x = pos.x - size.wIDth * anchorPoint.x    elseif alignType == display.CENTER_top or        alignType == display.CENTER or        alignType == display.CENTER_BottOM then        pos.x = pos.x - size.wIDth * anchorPoint.x + size.wIDth * 0.5    elseif alignType == display.RIGHT_top or        alignType == display.RIGHT_CENTER or        alignType == display.RIGHT_BottOM then        pos.x = pos.x - size.wIDth * anchorPoint.x + size.wIDth    end    if alignType == display.BottOM_left or        alignType == display.BottOM_CENTER or        alignType == display.BottOM_RIGHT then        pos.y = pos.y - size.height * anchorPoint.y    elseif alignType == display.CENTER_left or        alignType == display.CENTER or        alignType == display.CENTER_RIGHT then        pos.y = pos.y - size.height * anchorPoint.y + size.height * 0.5    elseif alignType == display.top_left or        alignType == display.top_CENTER or        alignType == display.top_RIGHT then        pos.y = pos.y - size.height * anchorPoint.y + size.height    end    return posend
在某个container中加入sprite,可指定根据container大小进行缩放及对齐方式
function MyPackage.displaySpriteOnContainer(sprite,container,scaletoFit,alignType)    if tolua.isnull(container) then        return    end    -- default settings    local scaletoFit = (scaletoFit ~= false)    local alignType = alignType or display.CENTER    if not tolua.isnull(sprite) then        local originSize = sprite:getContentSize()        if originSize.wIDth == 0 or originSize.height == 0 then            originSize = sprite:getCascadeBoundingBox()        end        local targetSize = container:getContentSize()        if targetSize.wIDth == 0 or targetSize.height == 0 then            targetSize = container:getCascadeBoundingBox()        end        if scaletoFit then            sprite:setScale(targetSize.wIDth / originSize.wIDth,targetSize.height / originSize.height)        end        -- NOTE: ignore container's anchor point        local pos = MyPackage.getpositionOfNode(container,alignType)        local leftBottomPos = MyPackage.getpositionOfNode(container,display.left_BottOM)        local posX = pos.x - leftBottomPos.x        local posY = pos.y - leftBottomPos.y        display.align(sprite,alignType,posX,posY)        container:addChild(sprite)    endend
总结

以上是内存溢出为你收集整理的quick-cocos2d-x tips全部内容,希望文章能够帮你解决quick-cocos2d-x tips所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1077109.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-26
下一篇2022-05-26

发表评论

登录后才能评论

评论列表(0条)

    保存