
原文请猛戳:
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 0endtable相关
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 hasValueendUTF8字符串
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所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)