Director scaleFactor doesn't apply to Sprites

Director scaleFactor doesn't apply to Sprites
0.0 0

#1

Hi,

I want to use ScaleFactor to automatically scale sprites so I used this standard Code:

// Set the design resolution
	glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::FIXED_HEIGHT);
    Size frameSize = glview->getFrameSize();
	
    // if the frame's height is larger than the height of medium size.
    if (frameSize.height > mediumResolutionSize.height)
    {        
        director->setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height, largeResolutionSize.width/designResolutionSize.width));
    }
    // if the frame's height is larger than the height of small size.
    else if (frameSize.height > smallResolutionSize.height)
    {        
        director->setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height, mediumResolutionSize.width/designResolutionSize.width));
    }
    // if the frame's height is smaller than the height of medium size.
    else
    {        
        director->setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height, smallResolutionSize.width/designResolutionSize.width));
    }

I get ScaleFactor of 0.9… for example but if I log my sprites scalefactor its 1
Do I have to do setScale(Director::getInstance()->getContentScaleFactor()) on every sprite?

Any help appreciated


#2

Settings content scale factor doesn’t directly affect scale value of sprites. It do all the work under the hood, if you just experiment with changing content scale factor to different values (0.5, 2.0) - you’ll see that picture changes.

When setting content scale factor you also want to use different sets of images :
e.g.
smallResolutionSize - images with scale 1x
mediumResolutionSize - 2x
largeResolutionSize - 4x

It’s my function of setting up a game for portrait mode (fixed width = 320):

void AppDelegate::setupScaleFactor(const float designWidth) {
    auto director = Director::getInstance();
    auto fileUtils = FileUtils::getInstance();
    auto glView = director->getOpenGLView();
    
    const float scaleFactor = glView->getFrameSize().width / designWidth;
    std::vector<std::string> resolutionOrder;
    float contentScaleFactor = 1.0;
    resolutionOrder.push_back("resources-iphone");
    if (scaleFactor > 1.7) {
        resolutionOrder.push_back("resources-iphonehd");
        contentScaleFactor = 2.0;
    }
    
    if (scaleFactor > 2.7) {
        resolutionOrder.push_back("resources-ipad");
        contentScaleFactor = 3.0;
    }
    
    if (scaleFactor > 3.7) {
        resolutionOrder.push_back("resources-ipadhd");
        contentScaleFactor = 4.0;
    }
    
    std::reverse(resolutionOrder.begin(),resolutionOrder.end());
    
    director->setContentScaleFactor(contentScaleFactor);
    fileUtils->setSearchResolutionsOrder(resolutionOrder);
}

If you are not using different sets of images then you shouldn’t provide different content scale factor.


#3

Hi,

thanks for your answer.
I tested different scale factors and saw how it changed, however what I don’t understand is how it works.
Why is the scale factor of sprites still 1.0?

And I thought that using different Resolution assets means you dont have to use content scale factor?
I think I really don#t understand the concept of content scale factor.


#4

contentScaleFactor of director and scale of sprites are different entities, and them don’t affect values of each other.

What is content scale factor? Image with size 100x100 will look good on device with resolution 320x480, but on device 640x960 it may look blurry. So you want to use 2x asset. But if you will just use 2x asset, then you will need to set sprite->scale=0.5 for each sprite… Quite a lot of work, agree? Especially if you didn’t think about it initially. That’s why concept of contentScaleFactor was introduces, to simplify this process - it says which ‘content’ set will be used (1x, 2x, 3x) and automatically adjusts it’s size. So after you setup it - you don’t worry about scales/sizes, etc.

1x image <=> contentScaleFactor = 1
2x image <=> contentScaleFactor = 2

You can think about contentScaleFactor as about density of the screen.


#5

Thanks for the help I will experiment some more


#6

You will need to do it for each sprite:

float scaleFactor = Director::getInstance()->getContentScaleFactor();
auto image = Sprite::create(imageName);
float designScale = .4 //here is where you put the scale while you are designing your UI
image->setScale(designScale * scaleFactor);