Trying to resize scene on orientation change

hello,

I am totally new to Cocos2d, please forgive my ignorance.

I am trying to adapt to different screen sizes and orientations in my game. So far I am writing for iOS. I have added UISupportedInterfaceOrientations to Info.plist with both landscape and portrait modes. Then I modified RootViewController.mm and changed shouldAutorotateToInterfaceOrientation to return YES for both landscape and portrait:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
    return UIInterfaceOrientationIsLandscape(orientation) || UIInterfaceOrientationIsPortrait(orientation);

now when I rotate the device (the simulator), it rotates the view, but the scale does not change, so in landscape mode the top portion of the scene is hidden.

my question is how to deal with this and how to change the size of my view while preserving the aspect ratio in response to orientation change?

thanks!
konstantin

What did you mean “the scale does not change”?

I have attached screenshots. as you see the top image shows the landscape mode. I need the game to scale proportionally so that the whole scene is visible vertically.

thanks for your help.

I also have met the similar issue after updating from 2.0-rc0a to 2.0.2.
When I setup app orientation to landscape (in XCode project settings) the director is initialized in portrait mode.
From debugging I can say that director initializes m_obScreenSize and m_obDesignResolutionSize from UIWindow bounds (portrait orientation).
Would be thankful for right approach.

I had the exact same problem but finally figured it out after many trial and error attempts.
Let me share my workaround to achieve multi-orientation, multi-size. :slight_smile:

For 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(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height),
    std::min(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height));
    } else {
    s = CGSizeMake(std::min(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height),
    std::max(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);

For 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):
    <pre>
    cocos2d::CCEGLView* view = cocos2d::CCDirector::sharedDirector~~>getOpenGLView;
    if {
    …
    } else {
    …
    if .width != w || view~~>getFrameSize.height != h) {
    view~~>setFrameSize(w, h);
    view->setDesignResolutionSize(w, h, kResolutionShowAll);
    }
    }
**Request for cocos2d-x team:**
  • I see there are few of us that develop apps supporting multiple orientations. The workaround solution works great for me, however it required me to modify the library code.
  • It would be great if this works without any library code change. (iOS #1 and #2, Android #1) Please consider supporting this case in future releases.

PW H, thank you. Works perfectly!

Volodymyr Ivanyshyn wrote:

PW H, thank you. Works perfectly!

Glad to see my solution worked for you as well.

I added a section about multiple orientation support (same content as the above) in wiki:
http://www.cocos2d-x.org/projects/cocos2d-x/wiki/About_device_orientation

Hi!

I have put those lines in those files and I have the same problem of the creator of this thread.

Here are my files:

main.cpp

void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv*  env, jobject thiz, jint w, jint h)
{
    cocos2d::CCEGLView* view = cocos2d::CCDirector::sharedDirector()->getOpenGLView();
//    if (!CCDirector::sharedDirector()->getOpenGLView())
    if(!view)
    {
        CCEGLView *view = CCEGLView::sharedOpenGLView();
        view->setFrameSize(w, h);

        AppDelegate *pAppDelegate = new AppDelegate();
        CCApplication::sharedApplication()->run();
    }
    else
    {
        ccDrawInit();
        ccGLInvalidateStateCache();

        CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
        CCTextureCache::reloadAllTextures();
        CCNotificationCenter::sharedNotificationCenter()->postNotification(EVNET_COME_TO_FOREGROUND, NULL);

    CCDirector::sharedDirector()->setGLDefaultValues();

    if (view->getFrameSize().width != w || view->getFrameSize().height != h) {
    view->setFrameSize(w, h);
    view->setDesignResolutionSize(w, h, kResolutionShowAll);
  }

    }
}

Cocos2dxRenderer.java

public void onSurfaceChanged(GL10 gl, int w, int h) {
    nativeInit(w, h);   
    }

AndroidManifest.xml

I can’t make it work :frowning:

Thank you.

How can we detect orientation change in cpp code? Is there some sort of event being fired?

I have tried this, and it seems to work, but is this how to handle orientation change events?

  1. Implement PW H modifications

  2. in main.cpp/void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit, add a postNotification for the orientation change so that PW H’s code looks like this

    …
    } else {
    …
    if (view->getFrameSize().width != w || view->getFrameSize().height != h) {
    view->setFrameSize(w, h);
    view->setDesignResolutionSize(w, h, kResolutionShowAll);
    CCNotificationCenter::sharedNotificationCenter()->postNotification(MSG_ORIENTATION_CHANGED, NULL);
    }
    }

  3. Add an observer in the init() function

    CCNotificationCenter::sharedNotificationCenter()->addObserver(this, callfuncO_selector(HelloWorld::orientationChanged), MSG_ORIENTATION_CHANGED, NULL);

  4. Add a handler that does whatever needs to be done (views don’t seem to resize by themselves)

    // put the view fullscreen, should I be checking CCEGLView frame size instead?
    void HelloWorld::orientationChanged(CCObject* obj) {
    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    setContentSize(winSize);
    }

is this wrong? Any more efficient ways to do it? Can this be applied to rotate a CCTableView and have it resize?

I am seeing lot of memory leak because of this code.
i suspect it is happening because of all the textures are loaded again.

if i remove the reload textures than the app does not show textures when i start it second time.

any solution for it ?

I preferred using separate function instead of nativeInit
as i am observing it is taking lot of time for reloading the textures which are not required for orientation change and i am seeing issues realated to memory leaks
so i modified the above step as

  1. Add nativeSurfacechange(w, h); to cocos2dx/platform/android/java/src_common/org/cocos2dx/lib/Cocos2dxRenderer.java ~~> void onSurfaceChanged.
  2. Add new method void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeSurfacechange;
    <pre>
    void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeSurfacechange
    {
    cocos2d::CCEGLView* view = cocos2d::CCDirector::sharedDirector~~>getOpenGLView;
    if
    {
    if .width != w || view~~>getFrameSize.height != h)
    {
    view~~>setFrameSize(w, h);
    // other processing required
    }
    }
    }

This thread is now a couple of years old… do we have support for device orientation changes in cocos2d-x yet?

3 Likes