Issue when implementing multi resolution support in AppDelegate.cpp

  • Random123abcxyz
    Likes 0

    Problem Description

    Hello again. I noticed that after implementing multi resolution support code from your video tutorial I have problems positioning nodes.

    Refer to this thread for all the details: http://discuss.cocos2d-x.org/t/how-to-use-scaleto-like/21553

    All of this happens only when I add multi resolution support, while with a clean AppDelegate.cpp everything works as expected, but of course with the wrong sprites :/

    Do you know how to overcome this issue?

    Thank you so much for the help, it’s fundamental to me :D


  • Sonar Systems admin
    Likes 0

    What’s the issue you are facing?


    This reply has been verified.
  • Random123abcxyz
    Likes 0

    I’ll make a couple examples.

    I tried positioning a node like this (the purpose was to make it appear anywhere in the screen but preventing to make it go off of it):

    this->setPosition(Vec2((arc4random() % (int)(visibleSize.width - visibleSize.width / 6)) + visibleSize.width / 12, (arc4random() % (int)(visibleSize.height - visibleSize.height / 3.5)) + visibleSize.height / 7));

    knowing that the node’s radius is

    (visibleSize.height / 12) + (arc4random() % (int)(visibleSize.height / 30)) - visibleSize.height /60)

    (it’s a dot)

    But this makes the node go off the screen (-y) when I use it with your AppDelegate.cpp version, to abbreviate it.

    Non considering that my code for positioning that node might be wrong in some way, also making something as simple as

    this->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));

    makes it disappear, while with a clean AppDelegate.cpp it is set to the center of the screen.

     


  • Sonar Systems admin
    Likes 0

    this->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));
     

    That shouldn’t make it disappear off the screen, can you show us the AppDelegate.cpp code


    This reply has been verified.
  • Random123abcxyz
    Likes 0

    Sure.

    #include "AppDelegate.h"
    #include "Scene.h"
    
    USING_NS_CC;
    
    AppDelegate::AppDelegate() {
    
    }
    
    AppDelegate::~AppDelegate() 
    {
    }
    
    //if you want a different context,just modify the value of glContextAttrs
    //it will takes effect on all platforms
    void AppDelegate::initGLContextAttrs()
    {
        //set OpenGL context attributions,now can only set six attributions:
        //red,green,blue,alpha,depth,stencil
        GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};
    
        GLView::setGLContextAttrs(glContextAttrs);
    }
    
    // If you want to use packages manager to install more packages, 
    // don't modify or remove this function
    static int register_all_packages()
    {
        return 0; //flag for packages manager
    }
    
    bool AppDelegate::applicationDidFinishLaunching() {
        // initialize director
        auto director = Director::getInstance();
        auto glview = director->getOpenGLView();
        if(!glview) {
            glview = GLViewImpl::create("IlMioPrimoGioco");
            director->setOpenGLView(glview);
        }
    
        // turn on display FPS
        director->setDisplayStats(true);
    
        // set FPS. the default value is 1.0/60 if you don't call this
        director->setAnimationInterval(1.0 / 60);
    
        register_all_packages();
        
        auto fileUtils = FileUtils::getInstance();
        auto screenSize = glview->getFrameSize();
        std::vector<std::string> resDirOrders;
        
        // check which assets the devices requires
        if ( 2048 == screenSize.width || 2048 == screenSize.height ) // retina iPad
        {
            resDirOrders.push_back("ipadhd");
            resDirOrders.push_back("ipad");
            resDirOrders.push_back("iphonehd5");
            resDirOrders.push_back("iphonehd");
            resDirOrders.push_back("iphone");
            
            glview->setDesignResolutionSize(1536, 2048, ResolutionPolicy::NO_BORDER);
        }
        else if ( 1024 == screenSize.width || 1024 == screenSize.height ) // non retina iPad
        {
            resDirOrders.push_back("ipad");
            resDirOrders.push_back("iphonehd5");
            resDirOrders.push_back("iphonehd");
            resDirOrders.push_back("iphone");
            
            glview->setDesignResolutionSize(768, 1024, ResolutionPolicy::NO_BORDER);
        }
        else if ( 1136 == screenSize.width || 1136 == screenSize.height ) // retina iPhone (5 and 5S)
        {
            resDirOrders.push_back("iphonehd5");
            resDirOrders.push_back("iphonehd");
            resDirOrders.push_back("iphone");
            
            glview->setDesignResolutionSize(640, 1136, ResolutionPolicy::NO_BORDER);
        }
        else if ( 960 == screenSize.width || 960 == screenSize.height ) // retina iPhone (4 and 4S)
        {
            resDirOrders.push_back("iphonehd");
            resDirOrders.push_back("iphone");
            
            glview->setDesignResolutionSize(640, 960, ResolutionPolicy::NO_BORDER);
        }
        else // non retina iPhone and Android devices
        {
            if ( 1080 < screenSize.width ) // android devices that have a high resolution
            {
                resDirOrders.push_back("iphonehd");
                resDirOrders.push_back("iphone");
                
                glview->setDesignResolutionSize(640, 960, ResolutionPolicy::NO_BORDER);
            }
            else // non retina iPhone and Android devices with lower resolutions
            {
                resDirOrders.push_back("iphone");
                
                glview->setDesignResolutionSize(320, 480, ResolutionPolicy::NO_BORDER);
            }
        }
        
        fileUtils->setSearchPaths(resDirOrders);
        
        // create a scene. it's an autorelease object
        auto scene = Scene::createScene();
    
        // run
        director->runWithScene(scene);
    
        return true;
    }
    
    // This function will be called when the app is inactive. When comes a phone call,it's be invoked too
    void AppDelegate::applicationDidEnterBackground() {
        Director::getInstance()->stopAnimation();
    
        // if you use SimpleAudioEngine, it must be pause
        // SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
    }
    
    // this function will be called when the app is active again
    void AppDelegate::applicationWillEnterForeground() {
        Director::getInstance()->startAnimation();
    
        // if you use SimpleAudioEngine, it must resume here
        // SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
    }
    

     


    This reply has been verified.
  • Sonar Systems admin
    Likes 0

    What device/emulator are you running it on?


    This reply has been verified.
  • Random123abcxyz
    Likes 0

    I’m running it on iPhone Simulator.

    Setting the dot to 

    setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));

    On iPhone 4S and iPhone 5 sizes the dot is completely off the screen, on iPad Retina it appears on center of x and almost at the bottom of y.

    Edit: plus on iPad Retina the background isn’t fixed to the screen’s size, there is a black space at the top.

    I set the background like this:

    Sprite *backgroundSprite = Sprite::create("Background.png");
    backgroundSprite->setPosition(Vec2(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2));
    backgroundSprite->setContentSize(Size(origin.x + visibleSize.width + (visibleSize.width / 4), origin.x + visibleSize.height + (visibleSize.height / 4)));
    this->addChild(backgroundSprite, -1);

    Edit 2: No. Maybe the background is my mistake. With the clean AppDelgate.cpp it is even worse :/

    Edit 3: Isn’t this:

    backgroundSprite->setContentSize(Size(origin.x + visibleSize.width + (visibleSize.width / 4), origin.x + visibleSize.height + (visibleSize.height / 4)));

    supposed to stretch the sprite? Using this with clean AppDelegate.cpp in iPad Retina Simulator I get black bands in top and right corners...


  • Random123abcxyz
    Likes 0

    Yes, replacing it with

    backgroundSprite->setScale(1.25);

    does it. Thanks.

    Do you know anything about the other issue?? I tried everything I could (I think), and I’m quite stuck at the moment :/

    Thanks again for all you do for us :)


  • Sonar Systems admin
    Likes 0

    Coudl you show some screenshots from different devices for the other problem.


    This reply has been verified.
  • Random123abcxyz
    Likes 0

    Here they are.

    Modified AppDelegate.cpp

    iPhone 4S:


    iPhone 5:


    iPhone 6 Plus:


    iPad Retina:


     


    Clean AppDelegate.cpp

    iPhone 4S:


    iPhone 5:


    iPhone 6 Plus:


    iPad Retina:




    Scene1.cpp

    #include "Scene1.h"
    #include "Dot.h"
    
    USING_NS_CC;
    
    Scene* Scene1::createScene()
    {
        // 'scene' is an autorelease object
        auto scene = Scene::create();
        
        // 'layer' is an autorelease object
        auto layer = Scene1::create();
    
        // add layer as a child to scene
        scene->addChild(layer);
    
        // return the scene
        return scene;
    }
    
    // on "init" you need to initialize your instance
    bool Scene1::init()
    {
        //////////////////////////////
        // 1. super init first
        if ( !Layer::init() )
        {
            return false;
        }
        
        Size visibleSize = Director::getInstance()->getVisibleSize();
        Vec2 origin = Director::getInstance()->getVisibleOrigin();
    
        Sprite *backgroundSprite = Sprite::create("Background.png");
        backgroundSprite->setScale(1.25);
        backgroundSprite->setPosition(Vec2(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2));
        this->addChild(backgroundSprite, -1);
        
        auto *newDot = Dot::create();
        this->addChild(newDot, 1);
        return true;
    }

    Dot.cpp

    #include "Dot.h"
    
    USING_NS_CC;
    
    // on "init" you need to initialize your instance
    bool Dot::init()
    {
        if ( !DrawNode::init() ) {
            return false;
        }
        
        Size visibleSize = Director::getInstance()->getVisibleSize();
        Vec2 origin = Director::getInstance()->getVisibleOrigin();
        
        this->clear();
        
        float radius = 1;
        float diameter = radius*2;
        Vec2 posVec = Vec2(visibleSize.width / 2, visibleSize.height / 2);
        
        this->setAnchorPoint(Point(0.5, 0.5));
        this->setContentSize(Size(diameter, diameter));
        this->setPosition(posVec);
        
        drawDot(Vec2(radius, radius), radius, Color4F::BLACK);
        
        auto scale = ScaleTo::create(0.5, (visibleSize.height / 12) + (arc4random() % (int)(visibleSize.height / 30)) - visibleSize.height /60);
        auto scale_ease = EaseBackOut::create(scale->clone());
        this->runAction(scale_ease);
        
        return true;
    }
    

     


    This reply has been verified.
  • Sonar Systems admin
    Likes 0

    Try pointing to the same directory aka the iPad retina one for checking if it is getting the black spot at all.


    This reply has been verified.
  • Random123abcxyz
    Likes 0

    You mean by pointing all the resolutions to the same directory in AppDelegate.cpp? Anyway I think that the dot is being drawn in every case, as you can see  in the GL Calls (I’ve actually drawn two dots, both in the center, forgot to say it). But it seems like it’s using the same “DesignResolutionSize” for every display resolution… This is just so weird!! Does it happen to you? I’ll check once again if I digited something wrong, then I think I’m going to see if this ever happens on the previous version of Cocos2d-x...

    ps: I also tried to create a new project, create a Dot class in it and drawing it directly in the HelloWorldScene with the modified. The result is just the same…

    ps: Sorry for the late!

  • Sonar Systems admin
    Likes 0

    It doesn’t happen to us and we are using the latest version, keep us informed.


    This reply has been verified.
  • Random123abcxyz
    Likes 0

    Ok… I wish I never asked this… I was expecting portrait resolutions to work in landscape mode!!

    If you see in my AppDelegate.cpp, every 

    glview->setDesignResolutionSize

    command has the inverted resolutions!

    In the iPad Retina Simulator it was possible to see the dot because the aspect ratio is 4:3.

    I’m really sorry I made you spend time for such a simple mistake. And thanks a lot again.

    ps: I’ve also added in my AppDelegate.cpp resolutions for iPhone 6, iPhone 6 Plus and some common Android resolutions, like 1920x1080, 1280x720, 960x540.

    You could update your tutorial n.4 on Youtube, maybe in the description or in your GitHub repo, it’ll be for sure helpful to someone :)


  • Sonar Systems admin
    Likes 1

    That’s cool, we are glad to hear you have solved it.

     

    We are going to be updating the entire series with better code and design.


    This reply has been verified.

Login to reply