研究了两天屏幕适配,了解了Cocos提供的屏幕适配的方案有下面几种:
1,EXACT_FIT
使用这个选项,可以保证设计区域完全铺满屏幕,但是可能会出现界面被拉伸。
2,SHOW_ALL
按原始比例进行缩放,图片不变形,为了保证缩放后较长的边也能完全显示,较短的边剩下的位置会用黑边填充,居中显示。
3,NO_BORDER
这个和上面的SHOW_ALL相反,按原始比例进行缩放,图片不变形,为了保证缩小后较短的边全屏显示,较长的边超出屏幕的部分会被裁剪,不会出现黑边,而且铺满屏幕
下面两种在Cocos2d-x 3.x版本里新添加的(没仔细了解):
4,FIXED_HEIGHT
保持传入的设计分辨率高度不变,根据屏幕分辨率修正设计分辨率的宽度。
适合高方向需要撑满,宽方向可裁减的游戏,结合setContentScaleFactor(RH/DH)使用
5、FIXED_WIDTH
保持传入的设计分辨率宽度不变,根据屏幕分辨率修正设计分辨率的高度。
适合宽方向需要撑满,高方向可裁减的游戏,结合setContentScaleFactor(RW/DW)使用。
使用的时候设置也很简单,按照我现在的理解,这个屏幕适配设置一次以后就无需再管理了,在function main 里添加:
cc.Director:getInstance():getOpenGLView():setDesignResolutionSize(设计分辨率的宽度,设计分辨率的高度,cc.ResolutionPolicy.NO_BORDER) -- NO_BORDER可以修改成上面任意一种模式
了解这些之后,觉得NO_BORDER是最合适的,然后继续研究如何做出游戏主菜单,我是使用Cocos Studio来做UI的,画好的UI如何导入到项目和使用这里就不详细说了,不了解的参考之前写的博客 查看,使用Cocos Studio做UI的时候,我的理解是画布的大小就是设计分辨率的大小,所以画布大小应该和程序里setDesignResolutionSize的宽高一致,比如设计的是一个以iphone4为准的横屏游戏,那画布的宽高就设置成960 * 640,对应的程序设置应该是setDesignResolutionSize(960,640,cc.ResolutionPolicy.NO_BORDER)
把做好的UI导入到程序里之后,在各个分辨率下运行,是自己期望的结果,到此屏幕适配研究完成了,但是使用NO_BORDER的方式适配屏幕会带来一个问题,就是根据运行设备屏幕的大小不同,有可能上下左右的某两条靠近边线一部分内容会被裁掉看不到,附上2张个效果图
我的Demo是基于960 * 640分辨率设计的
1,在960 * 640分辨率模拟器下运行效果:
2,在1280 * 720分辨率模拟器下运行效果:
可以明显的看到第2张图上下各有一部分因为分辨率的关系被裁剪了,但是这不是我期望的结果,我希望某些控件是始终能完全显示在界面上的,比如我的游戏名称logo
最终想到的一个解决方案是Cocos Studio弄两个Panel,一个负责加载绝对定位的控件,一个负责加载相对定位的控件,在程序载入UI之后,根据屏幕大小把负责加载相对定位的Panel大小修改成屏幕大小,这样这个Panel里面的控件就会根据先对定位显示到合适的位置,具体步骤如下:
在Cocos Studio里拖界面的时候,使用结构:
这里rootPanel是960 * 640大小的(全屏),activePanel是rootPanel的子视图,并且铺满rootPanel。
把不需要根据屏幕的变化而改变位置的控件放入到rootPanel里,比如开始游戏按钮,和界面的背景底图,设置rootPanel的子空间布局为绝对布局,然后activePanel的子空间布局设置成相对布局,这个时候放入activePanel里的控件位置是相对于activePanel的定位的
特别注意:
上面两点都会导致想要在程序里动态设置activePanel大小和位置的时候无效,血的教训呀!!!
把UI按照上面的思路画完之后,导入到项目里,这个时候需要做的是拿到activePanel对象、当前屏幕读取的分辨率大小、和从画布(UI界面)的什么位置开始读activePanel设置合适的位置和大小,然后把具体看下面代码:
local ui = rootNode:getChildByName("activePanel") -- 得到activePanel节点 local size = cc.Director:getInstance():getVisibleSize() -- 屏幕分辨率大小 local origin = cc.Director:getInstance():getVisibleOrigin() -- 从画布的某个点显示 -- 如果origin.x不等于0,表示是左右是被裁过的,把activePanel的x位置设置到屏幕里的0的位置 if origin.x ~= 0 then ui:setPositionX(ui:getPositionX() + origin.x) end -- y的设置理解同上,上下被裁过的 if origin.y ~= 0 then ui:setPositionY(ui:getPositionY() + origin.y) end -- 通过上面两个判断设置,ui在显示起始位置被固定好了,接下来设置ui的大小等于屏幕的大小,就大功告成了 ui:setContentSize(size)
做上面的处理,得到的结果就是期望的结果了,在960*640不会产生任何边变化,这里不贴图了
在1280 * 720下得效果图:
大功告成!!!
原文链接:https://www.f2er.com/cocos2dx/345101.html