Question

I have made android build using cocos2dx for the device having size 480*320 and it works fine but when i put the same build in another android device having size 640*480 the scaling issue occurs....

I am using following code to re-size automatically, but it is not working:

AppDelegate app;
CCEGLView& eglView = CCEGLView::sharedOpenGLView();
eglView.setViewName("Hello Lua");
eglView.setFrameSize(480, 320);

// set the design resolution screen size, if you want to use Design Resoulution scaled to current screen, please uncomment next line.
// eglView.setDesignResolutionSize(480, 320);
Was it helpful?

Solution

First of all, the code you have pasted is from main.cpp file which does not play a part when you compile the app for android or windows phone or ios. That file is for win32 project.

Now, for automatic scaling of app, the function in AppDelegate.cpp should set design resolution as well as policy. I use ExactFit policy because it stretches the app to fill the whole screen area and it works on Android , Windows, iOS everything (I have developed apps and tested) :

bool AppDelegate::applicationDidFinishLaunching()
{
    // initialize director
    CCDirector *pDirector = CCDirector::sharedDirector();
    pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
    // turn on display FPS
    CCEGLView::sharedOpenGLView()->setDesignResolutionSize(1200, 720, kResolutionExactFit);
    pDirector->setDisplayStats(false);

    pDirector->setAnimationInterval(1.0 / 60);

    CCScene *pScene = HelloWorld::scene();

    pDirector->runWithScene(pScene);
    return true;
}

You should also take a look at this Detailed explanation of multi-resolution support to understand it better.

OTHER TIPS

If you are not conscious about stretched look then do this. It will work on all the devices.

pDirector->setOpenGLView(pEGLView);

CCSize frameSize = pDirector->getOpenGLView()->getFrameSize();
CCLog("%.2f and %.2f is Frame size\n",frameSize.width,frameSize.height);
pEGLView->setDesignResolutionSize(960, 640, kResolutionExactFit);

Note: The above setting is for Landscape, if you need it for portrait just reverse the values like pEGLView->setDesignResolutionSize(640, 960, kResolutionExactFit)

The thing to understand here is that everything you will design on the coordinates of 640X960 and kResolutionExactFit will fix the things as Fit to the Screen. To do this more easily you should use Coocos Builder http://cocosbuilder.com/ and design everything on a custom layout of 640X960

I am recommending double resolution (640X960) because this way Quality won't be reduced and will look crisp on all kind of devices, however the drawback of Stretched Look would be there.

If you want to consider multiple resolutions in multiple way then you have to make multiple graphics and multiple Layouts, again Cocos Builder would be the best way to do this.

i.e for iPhone 5 it would be diff and for iPad and standard 480X320 it would be diff. To do this you can put checks on frame size to select respective View.

CCSize frameSize = pDirector->getOpenGLView()->getFrameSize();

You should experience some cutting at each side. This is done because is how best the compatibility mode match the screen res of 480x320. The others option are leaving some part of the height out or stretch the image (at cost of some performance (?) ).

The first can be easy done one the CCEGLView::create method, you can change the MIN to MAX in the scalefactor formula and its done, but this probably will breake all y position of your sprites :P

bool AppDelegate::applicationDidFinishLaunching()
{
    // initialize director
    CCDirector* pDirector = CCDirector::sharedDirector();
    CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();

    pDirector->setOpenGLView(pEGLView);

    // Set the design resolution
    // iPad size
    CCPoint res = CCPoint(768,1024);
    pEGLView->setDesignResolutionSize(res.x,
                                      res.y,
                                      kResolutionNoBorder);
  .....
}

Check the resolution and make changes for screen size: (This example is a portrait game)

typedef struct tagResource
{
   cocos2d::Size size;
   char directory[100];
}Resource;

std::vector<std::string> searchPath;
static Resource designResource =  { cocos2d::Size(768, 1024),  "ipad"};
static Resource smallResource  =  { cocos2d::Size(320, 480),   "iphone"};
static Resource galax7Resource =  { cocos2d::Size(600, 1024),  "gt_7p"  };
static Resource mediumResource =  { cocos2d::Size(768, 1024),  "ipad"};
static Resource galax10Resource =  { cocos2d::Size(800, 1280),  "gt_10p"};
static Resource fullHDResource  =  { cocos2d::Size(1080, 1920), "fullhd"};
static Resource largeResource  =  { cocos2d::Size(1536, 2048), "ipadhd"};
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
glview->setDesignResolutionSize(designResource.size.width, designResource.size.height, ResolutionPolicy::EXACT_FIT);
Size frameSize = glview->getFrameSize();
Resource realResource;
// if the frame's height is larger than the height of medium size.
if (frameSize.height > fullHDResource.size.height) {
    realResource = largeResource;
    CCLOG("largeResource");
} else if (frameSize.height > galax10Resource.size.height) {
    realResource = fullHDResource;
    CCLOG("fullHDResource");
} else if (frameSize.height > mediumResource.size.height) {
    realResource = galax10Resource;
    CCLOG("galax10Resource");
} else if (frameSize.height > smallResource.size.height) {
    if(frameSize.width > galax7Resource.size.width){
        realResource = mediumResource;
        CCLOG("mediumResource");
    }else {
        realResource = galax7Resource;
        CCLOG("galax7Resource");
    }
} else {
    realResource = smallResource;
    CCLOG("smallResource");
}
director->setContentScaleFactor(MIN(realResource.size.height/designResource.size.height, realResource.size.width/designResource.size.width));
searchPath.push_back(realResource.directory);
    auto fileUtils = FileUtils::getInstance();
fileUtils->setSearchPaths(searchPath);

I'm using cocos2dx V3 but the idea is the same for V2.

I have used Following resolution policy in my 3match game In AppDelegate.cpp

#define IS_LANDSCAPE

#ifdef IS_LANDSCAPE
static cocos2d::Size designResolutionSize = cocos2d::Size(1136,768);
#else
static cocos2d::Size designResolutionSize = cocos2d::Size(768,1136);
#endif

//==========================
bool AppDelegate::applicationDidFinishLaunching() {

    // initialize director
    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();
    if(!glview) {
        glview = GLViewImpl::create("My Game");
        director->setOpenGLView(glview);
    }

    // turn on display FPS
    director->setDisplayStats(false);

    // set FPS. the default value is 1.0/60 if you don't call this
    director->setAnimationInterval(1.0 / 60);

    // Set the design resolution
     glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::NO_BORDER);

    register_all_packages();

    // create a scene. it's an autorelease object
    auto scene =loading::createScene();

    // run
    director->runWithScene(scene);

    return true;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top