About device orientation
This article describes how to set device orientation on iOS and android.As you know, there are two ways to set device orientation:
- The OpenGL / cocos2d-x way
Faster, but doesn't rotate the UIKit objects(iOS) or widgets(android). - The ViewController way(iOS) or set by xml(android)
A bit slower, but the UIKit objects(iOS) or widgets(android) are placed in the right place.
The OpenGL way¶
You can set device orientation as follows:
CCDirector::sharedDirector()->setDeviceOrientation(kCCDeviceOrientationLandscapeLeft);
This way can only rotate objects rendered by the cocos engine, such as sprites or labels.
ViewController way(iOS)¶
The device orientation takes effect as follows:- Tell the system which orientations the application supports(RootViewController.mm)
// Override to allow orientations other than the default landscape orientation. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return UIInterfaceOrientationIsLandscape( interfaceOrientation ); }
- Add the view OpenGL rendered to the root view controller(AppController.mm)
// Use RootViewController manage EAGLView viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil]; viewController.wantsFullScreenLayout = YES; viewController.view = __glView;
The code is implemented in cocos2d-x as an iOS template.
Set device orientation in AndroidManifest.xml(android)¶
<application android:label="@string/app_name" android:debuggable="true" android:icon="@drawable/icon"> <activity android:name=".ApplicationDemo" android:label="@string/app_name" android:screenOrientation="landscape" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:configChanges="orientation"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
Conclusions¶
1. If you want to use OpenGL approach in iOS, don't use RootViewController.
2. If you want to use OpenGL way in Android, set the orientation to portrait in AndroidManifest.xml.
3. If you don't use any UIKit objects(iOS) or widgets(android) at all, then using OpenGL directly will be faster.
Supporting multiple orientations¶
Apply the following workaround to support multiple orientations as of cocos2d-x v2.0.2.
This patch may not be supported in future releases of cocos2d-x, or may become partially deprecated.
iOS¶
1. Comment out assert(m_eResolutionPolicy kResolutionUnKnown);
in cocos2dx/platform/ios/CCEGLView.mm::setContentScaleFactor(...)
.
2. Comment out CCAssert(m_bIsRetinaEnabled false, "can not enable retina while set design resolution size!");
in cocos2dx/platform/CCEGLViewProtocol.cpp::setDesignResolutionSize(...)
.
3. Return true in shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
.
4. In (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
, add:
CGSize s; if (UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation)) { s = CGSizeMake(std::max<float>(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height), std::min<float>(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height)); } else { s = CGSizeMake(std::min<float>(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height), std::max<float>(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height)); } cocos2d::CCDirector* director = cocos2d::CCDirector::sharedDirector(); director->enableRetinaDisplay(false); director->getOpenGLView()->setFrameSize(s.width, s.height); director->getOpenGLView()->setDesignResolutionSize(s.width, s.height, kResolutionShowAll); director->enableRetinaDisplay(true);
Android¶
1. Add nativeInit(w, h);
to cocos2dx/platform/android/java/src_common/org/cocos2dx/lib/Cocos2dxRenderer.java
-> void onSurfaceChanged(GL10 gl, int w, int h)
.
2. Add this code to void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)
:
cocos2d::CCEGLView* view = cocos2d::CCDirector::sharedDirector()->getOpenGLView(); if (!view) { ... } else { ... if (view->getFrameSize().width != w || view->getFrameSize().height != h) { view->setFrameSize(w, h); view->setDesignResolutionSize(w, h, kResolutionShowAll); } }