笔者所使用的方案经历了正式的线上项目使用,请放心食用
假设项目的设计分辨率为1920x1080
一、全平台通用逻辑
无论是Android、IOS还是h5,进行横竖屏切换,都需要执行下面对应代码,
而h5执行之后,就能完美适配横竖屏切换了。
Andriod、IOS 还需要一些其他的处理。
首先
// 获取屏幕物理分辨率
let frameSize = cc.view.getFrameSize()
竖屏
cc.view.setOrientation(cc.macro.ORIENTATION_PORTRAIT)
if (frameSize.width > frameSize.height)
cc.view.setFrameSize(frameSize.height, frameSize.width)
// this.canvas 为当前fire场景的画板
this.canvas.designResolution = cc.size(1080, 1920)
横屏
cc.view.setOrientation(cc.macro.ORIENTATION_LANDSCAPE)
if (frameSize.height > frameSize.width)
cc.view.setFrameSize(frameSize.height, frameSize.width)
this.canvas.designResolution = cc.size(1920, 1080)
二、Android原生处理
竖屏
// instance 为AppActivity,我的做法是做了对象 public static AppActivity instance,然后在 onCreate 赋值
instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
横屏
// instance 为AppActivity,我的做法是做了对象 public static AppActivity instance,然后在 onCreate 赋值
instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
上面的两个函数,需要脚本层通过反射调用。
三、IOS原生处理
// 首先,将设备方向设为未知,这段必要,否则直接切换横竖屏,有可能会切换失败
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationUnknown] forKey:@"orientation"];
float w = cocosView.bounds.size.width;
float h = cocosView.bounds.size.height;
竖屏
oMask = UIInterfaceOrientationMaskPortrait;
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:@"orientation"];
if (w > h){
cocosView.bounds = CGRectMake(0, 0, h, w);
}
横屏
oMask = UIInterfaceOrientationMaskLandscape;
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationLandscapeRight] forKey:@"orientation"];
if (h > w){
cocosView.bounds = CGRectMake(0, 0, h, w);
}
最后不管横竖屏
cocosView.center = CGPointMake(cocosView.frame.size.width * 0.5, cocosView.frame.size.height * 0.5);
四、Android、IOS 通用脚本处理
IOS、Android设备在屏幕旋转的时候并不会触发布局重新刷新,但是我们可以主动调用事件触发刷新
window.dispatchEvent(new cc.Event.EventCustom('resize', true))
为什么resize能刷新能,你可以在CCWidgetManager.js,找到如下代码
init: function init(director) {
...
if (cc.sys.isMobile) {
window.addEventListener('resize', this.onResized.bind(this));
}
...
}
onResized: function onResized() {
var scene = cc.director.getScene();
if (scene) {
this.refreshWidgetOnResized(scene);
}
}
更详细的自己去跟踪引擎代码吧。
至此全平台的屏幕旋转实现。