Cocos2dx中应用内部横竖屏切换
{
未实践
https://blog.csdn.net/ByAlick/article/details/83009941
}
{
语言环境:
Cocos2dx 3.6
Lua 5.1
Android Studio 3.0.1
问题:如何在应用内部进行横竖屏切换?
解决思路:
由于产品需求,必须在应用内部进行横竖屏切换(苦比〜_〜),没办法,网上教程一大把,大多数是在一开始就定义好了的屏幕,无法做到自由切换,没几个详细的,连个参考的例子都没有,初步思路:以安卓平台为例,
在需要切换时,先改变相应平台的屏幕设置,在获取当前的场景,将有关于场景位置坐标的类重新定义,就完成了一个切屏操作。
详解:
安卓的平台:
在安卓平台的的AndroidManifest.xml文件中需要如下配置:
<activity android:name="org.cocos2dx.lua.AppActivity"
android:label="@string/app_name"
android:screenOrientation="sensorLandscape" //开始时屏幕的状态
android:launchMode="singleTask"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:configChanges="keyboardHidden|orientation|screenSize"> //重点:定义允许的切屏操作
</activity>
接下来在主程序文件中定义一个屏幕状态变量
public static int AppOrientation = -1; //屏幕方向 默认-1横屏2 竖屏1
重载Cocos2dxActivity类的onConfigurationChanged方法,不懂的可以去了解下这个方法的作用,这里不做说明:
@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
String msgText = "AppActivity 提示:---->";
// 屏幕旋转
if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
AppOrientation = newConfig.orientation;
msgText = msgText + "横屏";
}else if(newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
AppOrientation = newConfig.orientation;
msgText = msgText + "竖屏";
}
System.out.println(">>>>>>>>>>>>>>>"+msgText+"<<<<<<<<<<<");
}
接下来开始具体实现:
//设置应用的旋转方向、重力感应
// 参数1:1:横屏,2:竖屏,3根据用户朝向
//参数2:重力感应 0开启 1关闭
public static int setOrientation(int orientation, int gravity){
System.out.println("调用成功:------------>"+ String.valueOf(orientation) + String.valueOf(gravity));
//旋转方向
if(orientation == 1 ) {
instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
AppOrientation = 2;
}else if (orientation == 2 ){
instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
AppOrientation = 1;
}else if (orientation == 3 ) {
instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
AppOrientation = 3;
}
//重力感应设置
if(gravity == 0){
instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}else if(gravity == 1){
instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
}
return 0;
}
在此设置函数中,增加了重力感应扩展,可用可不用,当然,既然是设置,肯定需要重载设置函数
@Override
public void setRequestedOrientation(int requestedOrientation) {
super.setRequestedOrientation(requestedOrientation);
}
为了脚本层的调用,增加了获取函数
//获取应用的旋转方向
public static int getOrientation(){
return AppOrientation;
}
至此,平台的设置就完成了,到这一步,已经完成了屏幕的切换,接下来是脚本层的设置,完成坐标的重定义;
LUA:
在LUA脚本中,首先完成初始屏幕设置(个人需求)以及后面要用到的屏幕定义参数:
sysytem.lua:
-- screen orientation(横竖屏)
CONFIG_SCREEN_ORIENTATION = "landscape" --portrait
-- system direction(系统方向 )
SYSTEM_SCREEN_ORIENTATION = -1 -- -1:未设置 1:竖屏 2:横屏 3:用户当前首选
-- Whether to switch screens(切换屏幕判断)
SYSTEM_SCREEN_JUDHE = false
-- design resolution(设计分辨率)
CONFIG_SCREEN_WIDTH = 1334
CONFIG_SCREEN_HEIGHT = 750
-- auto scale mode(屏幕适配方式)
CONFIG_SCREEN_AUTOSCALE = "SHOW_ALL" --SHOW_ALL FIXED_WIDTH
接下来修改框架中的显示方法:
要做到的是应用中切换屏幕,所以场景肯定是在之前就一定存在的,改之前请确保你的屏幕适配是正确的
--检查设备屏幕尺寸
local glview = sharedDirector:getOpenGLView()
if nil == glview then
glview = cc.GLViewImpl:create("QuickCocos",
cc.rect(0, 0, CONFIG_SCREEN_WIDTH or 900, CONFIG_SCREEN_HEIGHT or 640))
sharedDirector:setOpenGLView(glview)
else
local PLATFORM_OS_ANDROID = 3
local PLATFORM_OS_IPHONE = 4
local PLATFORM_OS_IPAD = 5
--设定设计分辨率
if platform == PLATFORM_OS_ANDROID or platform == PLATFORM_OS_IPHONE or platform == PLATFORM_OS_IPAD then
if SYSTEM_SCREEN_JUDHE == true then
glview:setFrameSize(CONFIG_SCREEN_WIDTH or 900, CONFIG_SCREEN_HEIGHT or 640)
end
end
end
重点在于以上代码的东西,至于SYSTEM_SCREEN_JUDHE的判断,是由于存在多个场景切换,当场景存在且要设定的设计分辨率与当前场景的一致时,会出现屏幕可视区域超出的情况,具体原因尚未查明。
接下来在框架的init.lua初始化类中配置SYSTEM_SCREEN_JUDHE的初始化设置,在require display之前这样设置
if SYSTEM_SCREEN_JUDHE == nil then
SYSTEM_SCREEN_JUDHE = false
end
接下来开始入口:main.lua 中位置坐标的重定义,
--坐标重置
function _RESET_DISPLAY_CLASS(isChange)
if isChange ~= true then
SYSTEM_SCREEN_JUDHE = false
else
SYSTEM_SCREEN_JUDHE = true
end
-- 记录下当前已经加载的文件
for k, _ in pairs(package.loaded) do
if k == "hall.src.app.extends.panel" then
package.loaded[k] = false
end
if k == cc.PACKAGE_NAME .. ".cc.init" then
package.loaded[k] = false
end
if string.find(k,cc.PACKAGE_NAME) ~= nil then
package.loaded[k] = false
end
if string.find(k,"hall.src.cocos") ~= nil then
package.loaded[k] = false
end
end
cleanPackageSnapshot()
require("hall.src.cocos.init")
require(cc.PACKAGE_NAME .. ".init")
require("hall.src.app.extends.panel")
end
每个项目框架的位置坐标类都不同,这只是我的项目框架,在重加载位置坐标时,请注意以下几点:
1.必须先清除已加载的位置类
2.重新加载时请尽量参照正常加载的顺序
3.若位置类中包含全局变量必须初始化
4.能用局部变量的最好用局部
}