关于适配,简单得介绍一下原理,就是游戏一般有2个窗口大小得设置,一个是屏幕大小另一个是设计屏幕大小,这2个其实很容易理解,但是在现实中,我们有得游戏设计得尺寸大小是 1280 *720 或者是 960*640 ,现在得手机屏幕越来越大,像素也是越来越牛批,导致1280*720根本铺不满整个屏幕了,这个时候就要用到一个适配了,这也是很多公司面试得时候喜欢问你得东西。下面得这种方案是我用到得一种,就是把所有得节点放到同一个背景上,然后把背景拉伸,再把背景上得所有得节点X坐标增加偏移量,这个偏移量是手机得屏幕大小和我们设计像素大小得差值得一半,而Y坐标不变。
function UITool.AdaUI(SceneChildArr, ScaleNodeArr)
if type(SceneChildArr) ~= "table" then
SceneChildArr = { SceneChildArr }
end
if type(ScaleNodeArr) ~= "table" then --需要被缩放的背景遮罩等但是其子节点不缩放-锚点(0.5,0.5)--
ScaleNodeArr = { ScaleNodeArr }
end
local WinSize = cc.Director:getInstance():getWinSize()
local DesignSize = cc.size(DESIGN_WIDTH, DESIGN_HEIGHT)
local MoveX = (WinSize.width - DesignSize.width ) / 2
for _, pNode in pairs(SceneChildArr) do
pNode:setPositionX(pNode:getPositionX() + MoveX)
end
for _, pNode in pairs(ScaleNodeArr) do
local ScaleX = WinSize.width / DesignSize.width
pNode:setScaleX(ScaleX)
for _, ChildNode in pairs(pNode:getChildren()) do
ChildNode:setScaleX(1 / ScaleX)
end
end
end
看到上面得是不是就清晰了。下面展示一下我们如何加载csb然后简化官方得节点查找方案以及回调:
function UITool.Load(CSBPath,Root,ChildNodeNameT)
ChildNodeNameT=ChildNodeNameT or {}
local NormalNode={}
for _,NName in ipairs(ChildNodeNameT) do
assert(NormalNode[NName]==nil,"不支持绑定同名的节点,遇到这样的情况请只绑定它们的父节点,然后在需要的地方用getChildByName获取即可: "..NName)
NormalNode[NName]=true
end
local UIRootNode=cc.CSLoader:createNode(CSBPath,function(NodeObj)
local NodeName=NodeObj:getName()
if Root[NodeName] then
assert(false,"不支持绑定同名的节点,遇到这样的情况请只绑定它们的父节点,然后在需要的地方用getChildByName获取即可: "..NodeName)
end
local IsCloseBtn=string.find(string.upper(NodeName),"CLOSE")
if IsCloseBtn and NodeObj.loadTextures then --带名字带Close的都认为是关闭按钮--
if NodeObj.setScale9Enabled and NodeObj.ignoreContentAdaptWithSize then
NodeObj:setScale9Enabled(false)
NodeObj:ignoreContentAdaptWithSize(true)
end
NodeObj:loadTextures("CloseBig0.png","CloseBig1.png","CloseBig1.png",UI_TEX_TYPE_PLIST)
AssTool.DebugUI(NodeObj)
end
local IsLabelBtn=string.find(NodeName,"^BtnLab")
if IsLabelBtn then
NodeObj:setTouchEnabled(true)
NodeObj:AddXiaHuaLine() --下划线--
end
if ChildNodeNameT[NodeName] then
Root[NodeName]=NodeObj
assert(type(ChildNodeNameT[NodeName])=="function" or type(ChildNodeNameT[NodeName])=="table", "NOT FUNCTION!!!")
if type(ChildNodeNameT[NodeName])=="function" then
if string.find(NodeName,"^CB_") then --复选框的节点名字前缀为CB_以区分普通按钮--
Root[NodeName]:addEventListener(function(pSender,eType)
PlayAudio.play(AssTool.getSoundRes(IsCloseBtn and 30018 or 30017))
ChildNodeNameT[NodeName](pSender,eType)
end)
else --按钮--
Root[NodeName]:addClickEventListener(function(pSender)
if not string.find(NodeName,"_NOS") then --非通用音效或者无音效--
PlayAudio.play(AssTool.getSoundRes(IsCloseBtn and 30018 or 30017))
end
ChildNodeNameT[NodeName](pSender)
end)
Root[NodeName]:setTouchEnabled(true)
end
elseif type(ChildNodeNameT[NodeName])=="table" then --1是类型-2是点击事件-3是触摸事件-4是设置标签--
if ChildNodeNameT[NodeName][1] == 1 then
Root[NodeName]:addClickEventListener(function(pSender)
PlayAudio.play(AssTool.getSoundRes(IsCloseBtn and 30018 or 30017))
ChildNodeNameT[NodeName][2](pSender)
end)
Root[NodeName]:addTouchEventListener(function(pSender, touchType)
PlayAudio.play(AssTool.getSoundRes(IsCloseBtn and 30018 or 30017))
ChildNodeNameT[NodeName][3](pSender, touchType)
end)
Root[NodeName]:setTag(ChildNodeNameT[NodeName][4])
end
end
else
if NormalNode[NodeName] then
Root[NodeName]=NodeObj
end
end
end
end)
return UIRootNode
end
方法有了,那来一个实例看一下:
好了,一个简单得屏幕适配方案以及一个简单得csb加载就这么结束了。