屏幕旋转实现方案,支持全平台

最近需要在我们横版游戏接入一个webview,而webview是竖版的,就鼓捣了下设备屏幕旋转,同时支持web,android,ios平台,下面是实现方案(初始方向为横版):

  1. 设置屏幕旋转 cc.view.setOrientation(),这个API的描述文档写着对native无效,实际上还是有影响的
  2. 设置framesize为对应方向的尺寸 cc.view.setFrameSize()
  3. 更改canvas的 designResolution 和其他参数

WEB平台: web平台本身就支持旋转,执行上面步骤就可以完美适配

ANDROID平台(AppActivity.java里添加以下代码,需要import android.content.pm.ActivityInfo;):

public static void setOrientation(String dir){
    if(dir.equals("V"))
        ((AppActivity)(SDKWrapper.getInstance().getContext())).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
    else
        ((AppActivity)(SDKWrapper.getInstance().getContext())).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}

((AppActivity)(SDKWrapper.getInstance().getContext()))只是为了拿到AppActivity的实例,你也可以存个变量


IOS平台(AppController.mm里添加以下代码):

UIInterfaceOrientationMask oMask = UIInterfaceOrientationMaskLandscape;

-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    return oMask;
}

+(void)setOrientation:(NSString*)dir{
    if([dir isEqualToString:@"V"]){
        oMask = UIInterfaceOrientationMaskPortrait;
        [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:@"orientation"];
    }
    else{
        oMask = UIInterfaceOrientationMaskLandscape;
        [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationLandscapeRight] forKey:@"orientation"];
    }
}

ios平台的查了些资料,发现好多实现都是需要同时勾选设备的横向、竖向,最后才发现用supportedInterfaceOrientationsForWindow可以很容易实现。
oMask的初始值要与你项目的Device Orientation相同,我的demo中是勾选了 LandScape Left 和 LandScape Right。
下面的项目demo
rotate.zip (7.9 KB)

15赞

在实际应用中,我们需要对UI做很多适配,用Widget组件可以很容易实现,我发现原生平台上屏幕旋转后并不会触发Widget的布局重新刷新(ONCE 和 ON_WINDOW_RESIZE都不会触发),通过查看源码发现widget组件是通过监听resize事件重新布局的,所以可以手动调用触发:
window.dispatchEvent(new cc.Event.EventCustom(‘resize’, true))

所以,必须要手动触发····
但 这算不算引擎的疏漏???
要不要@引擎组的大大们看下?

1赞

mark

Mark马克

demo是用2.0.10做的
理论上我觉得setFrameSize变了,应该可以认为窗口发生变化,去触发widget重新布局

所以,请求引擎组大佬帮忙,看下,这块是应该自己手动触发,还是引擎自动触发
@337031709 @huanxinyin

所以,必须要手动触发····
但 这算不算引擎的疏漏???

大佬,为啥这样的写法用在大厅加子游戏模式的项目上会失效呢,测试的是安卓端,分辨率有变化但是设备屏幕不会转。

Mark

不清楚啊,我没有相关环境,但理论上跟大厅子游戏无关的,旋转是调用安卓底层实现的,你可以看下log,看点击旋转时有没有什么报错信息。
我使用的是creator2.0.10,在安卓9.0和4.4系统上测试都是ok的。

子游戏里的方法没法调取到AppAcrivity里的的setOrientation,我是个小白对安卓没啥了解,然后不懂该怎么做了~~~

我是旗帜

你在AppAcrivity去写这个函数啊·····内容上面也说了

哥们,按照你的方法,在iOS模拟器上,出现这样的情况,知道是怎么回事吗?

你这个问题解决了吗 我现在也碰到一样的问题了

正web 上是没有问题,但是在初始的时候,界面本身是横屏设计的,然后初始化为竖屏的时候,界面缩小了,横屏是正常的。这个 要修改哪里、?

应该是需要在 iOS 代码处重新设置下cocos view的大小

额,发现是有这个问题,但发现好像随便操作下就回复正常了。
翻转屏幕有个动画过程,我猜测是不是因为这个导致后面重新设置view等的操作未生效,可以考虑下,翻转完延时处理。
最近在忙别的,我抽个时间看看能不能解决这个问题。

插插插插

有解决办法了么 我现在也碰到一样的问题了