I’m using cocos2d-x 2.1.4 along with Marmalade 6.3.1 and this has been tested on the following: iPhone 4S, iPad 4, Blakberry Playbook and Xperia Play, but this issue only affects iOS devices.
In portrait orientation everything works as expected, but in landscape mode, it seems that width and height values for visible size are switched, as if the device was still in portrait mode, although visible origin has the correct values. This issue occurs both with CCDirector::sharedDirector()->getVisibleSize() and with CCEGLView::sharedOpenGLView()->getVisibleSize().
To make things clearer, I put together a scene with 5 sprites, one at the center of the screen and one on each corner, each with a different color (apologies for the blue one on the bottom right corner, it’s not easy to see it in the screenshots). To position them, I used the VisibleRect class from the TestCpp sample:
void VisibleRect::lazyInit()
{
if (s_visibleRect.size.width == 0.0f && s_visibleRect.size.height == 0.0f)
{
s_visibleRect.origin = CCDirector::sharedDirector()->getVisibleOrigin();
s_visibleRect.size = CCDirector::sharedDirector()->getVisibleSize();
}
}
CCPoint VisibleRect::center()
{
lazyInit();
return ccp(s_visibleRect.origin.x+s_visibleRect.size.width/2, s_visibleRect.origin.y+s_visibleRect.size.height/2);
}
// etc
Running the application on iOS devices, this is the result
Which looks a lot like swapped values between width and height, so I tried switching them manually as such:
void VisibleRect::lazyInit()
{
if (s_visibleRect.size.width == 0.0f && s_visibleRect.size.height == 0.0f)
{
s_visibleRect.origin = CCDirector::sharedDirector()->getVisibleOrigin();
s_visibleRect.size = CCSizeMake( CCDirector::sharedDirector()->getVisibleSize().height, CCDirector::sharedDirector()->getVisibleSize().width );
}
}
And as a result I got this:
Which is what it should look like alright. The problem with this method is that the x and y values for touch events are also swapped, so if I were to use this workaround, I’d have to fiddle with touch values as well. Here’s my AppDelegate init code:
bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
CCSize screenSize = CCEGLView::sharedOpenGLView()->getFrameSize();
CCSize designSize = CCSizeMake(1024, 768);
std::vector searchPaths;
if (screenSize.height > 320)
{
searchPaths.push_back("hd");
searchPaths.push_back("sd");
pDirector->setContentScaleFactor(768.0f/designSize.height);
}
else
{
searchPaths.push_back("sd");
pDirector->setContentScaleFactor(320.0f/designSize.height);
}
CCFileUtils::sharedFileUtils()->setSearchPaths(searchPaths);
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionNoBorder);
// turn on display FPS
pDirector->setDisplayStats(false);
// set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 / 60);
// create a scene. it's an autorelease object
CCScene *pScene = MenuScene::scene();
// run
pDirector->runWithScene(pScene);
return true;
}
Is this a bug with visibleSize and landscape orientation or am I missing something? Since I’m using Marmalade, I set the orientation in the app.icf file as such:
[S3E]
DispFixRot="FixedLandscape"
The wiki has an article about [[Device_Orientation]] but it’s no longer up to date, so I don’t know if there’s anything there that could help me. Thanks in advance!