Scaling font size of label according to screen size in cocos 2d-x

Is there a way by which I can scale the font size of labels based on the screen size/device resolution?I am using labels with ttf fonts with a single font size and I’d like to scale the font size based on screen size as it appears proper on narrower devices whereas it appears too big on wider devices.

Any help would be appreciated!
Thanks.

Folks tend to calculate the screen size and create a scale factor in which you can multiply your font size by. There are plenty of topics here that talk about it.

Hi Alwyn

Remember that if the design resolution size doesn’t change, the appearance of your game remain the same!

Example:

  • Design resolution Size : 1920 x 1080
  • Device 1 screen size: 1280 x 720
  • Device 2 screen size: 2560 x 1440

In this case a ttf Label of size, let’s say 50, appears the same on device 1 and device 2, even if device 2 has 4x pixels than device 1!
When also changes the resolution ratio between devices, the result depend on the choose of design resolution polices!
I strongly suggest to read this document:
http://www.cocos2d-x.org/wiki/Multi_resolution_support

Bye

1 Like

@drakon99 Thanks.I’ve gone through the link on Multi Resolution support before but I did not get an idea on how to go about it.Anyways your explanation has brought about more clarity on design resolution size.Further to this,the link on multi resolution support calculates content scale factor based on height since the resources are loaded according to height of screen.Considering that I load my resources based on screen width,how can we calculate content scale factor for that?

i use the following.

winSize.width = 1136; //design resolution width
winSize.height = 640;  //design resolution height

Size actualWinSize = Director::getInstance()->getWinSizeInPixels();

this->setScaleX(actualWinSize.width/winSize.width);
this->setScaleY(actualWinSize.height/winSize.height);
this->setAnchorPoint(Point::ZERO);

//This doesn’t require multiple size of resources/assets

//This will stretch the current layer(this) to fit the screen
//some elements that you don’t want to be stretched i use the following code afterwards

void Shared::rescale(Node *node,float scale){

Size winSize;
winSize.width = 1136;
winSize.height = 640;

Size actualWinSize = Director::getInstance()->getWinSizeInPixels();

float factorX = actualWinSize.width/winSize.width;
float factorY = actualWinSize.height/winSize.height;

float minVal = MIN(factorX, factorY);
node->setScaleX((scale/factorX) * minVal);
node->setScaleY((scale/factorY) * minVal);

}

//simply pass the sprite to this function to make it unstretched and a perfect fit by size

Sprite *sp = Sprite::create(“xyz”);
this->addChild(sp);

Shared::rescale(sp,1.0f);

i hope this helps :smiley:

Well, another key element for multi resolution factor is the “contentScaleFactor” (CSF).
In my experience I noticed this facts:

  • CSF does NOT modify your design resolution size! (great thing :smile: )
  • if CFS is > 1 than Sprites (but also bitmap fonts) in your game will have SMALLER size (sprite->getContentSize() / CSF)
  • if CFS is < 1 than Sprites (but also bitmap fonts) in your game will have BIGGER size (sprite->getContentSize() / CSF)
  • CFS does not modify TTF font appearance

If you want to make bigger or smaller TTF fonts according the CSF you can use this simple function:

float adjustTtfFontSize(float size) {
    const float csf = Director::getInstance()->getContentScaleFactor();
    return size / csf;
}

But if you modify CSF likely you have to prepare different asset folders for each resolution you are interested in!
Then you should use search paths to choose the right folder (as in the document you read).

1 Like

I think you can achieve the same result without scaling in this simpler way:

  • Fix a design resolution size (es. 1920x1080)
  • Use the policy EXACT_FIT

The game will appear the same in all the 16:9 screens, appears “stretched” (but still filling the screen) in the devices with resolution ratio different from 16:9.

Bye

Got it.I have one last clarification.In the document they have used a design resolution size of (480,320) for iphone.How to choose the design resolution size to be set on the glView?Considering that I’m building my game to support iPhone 4s until iPhone 6+,which is the design resolution size I could opt for?

Personally I suggest to use a 16:9 design resolution (the majority of smartphone are 16:9) like 1280x720 or 1920x1080.
Then for the non 16:9 devices (like iPhone 4s) you need a policy.
You could use the policy “SHOW_ALL” to make the game to have the same proportion on all screens but with black bars to fill space in non 16:9 resolution ratios.
A better choice (I suggest) could be to use “FIXED_HEIGHT”.
In this case the design resolution height remains the same on all the devices, but the width will be adjusted in non 16:9 devices (e.g. in iPhone 4S becomes larger ).
This implies that you cannot use “magic number” for Node positioning but should always rely on current visible size.

A little example for centering a sprite supposing FIXED_HEIGHT policy:

auto visibleSize = Director::getInstance()->getVisibleSize();
auto sprite = Sprite::create("someSprite.png");
sprite->setPosition({visibleSize.width * 0.5f, visibleSize.height * 0.5f});
addChild(sprite);

Bye