Honestly it took me ages to get my head around it - and I basically read all the stuff on here but it just wasnāt sinking in - so I wrote a simple āgameā that put a sprite, that was a png at the design resolution, in the centre of the screen.
Then ran it at different design resolutions with different settings;
That shows the different ways it can be displayed:
e.g. for a design of 1024 x 768
- screen resolution = 1024 x 768 = ideal solution
- screen resolution = 512 x 394 = either just see middle of sprite or sprite is shrunk to fit, but then fits
- screen resolution = 2048 x 1536 - either see sprite in the middle of black area, or sprite is zoomed to fit, but then fits
- screen resolution = 2000 x 768 = Either black bars left and right or zoomed in and lose top and bottom
- screen resolution = 1024 x 900 = Either black bars top and bottom or zoomed in and lost left and right
You get the idea - once Iād played with that, and played with the settings, I came up with a solution that suited me for my game (essentially I provide assets in 4 resolutions and use different assets depending on the device. The design resolution is slightly smaller that the highest screen resolution I expect to supportā¦
Some snippets of code from my AppDelegate belowā¦
// Define all our resource types and locations
static Resource ultraResource = { Size(2048, 1536), "UD"};
static Resource hiResource = { Size(1920, 1080), "HD" };
static Resource stdResource = { Size(960, 640), "SD" };
static Resource lowResource = { Size(570, 320), "LD" };
// Declare the resolution we designed the game at
static Size designResolutionSize = Size(1920, 1080);
ā¦
// Tell cocos our design resolution and our resolution policy
glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::FIXED_HEIGHT);
// The vector we will use to build a list of paths to search for resources
std::vector<std::string> searchPaths;
// Get the actual screen size
Size frameSize = glview->getFrameSize();
// Define a silly scale factor so we know when we have calculated it
float scaleFactor = -1;
int widthDiff = 999;
Resource found = ultraResource; // Default to this in case we find a resolution we plain can't figure out!
// Look through our resource definitions
for (auto resource : resources)
{
// Calculate the Horizontal ratio for the resouces (i.e. Resource Height / Device Height
float ratio = resource.size.height / frameSize.height;
// Calculate the scaled widths based on the horizontal ratio
float scaleWidth = resource.size.width / ratio;
// Calculate the Width Differences (i.e. how much bigger is the resource than the screen, width wise- so how many pixels are we going to lose?
int diff = scaleWidth - frameSize.width;
// If the width difference is < -1 we'd have black bars, so ignore it (single pixel is fine!)
// If the scale factor is > 2 we're scaling a bit too much, ignore it
// If the scale factor is < 0.5 we're scaling a bit to much, ignore it
if (diff >= -1 && ratio <= 2 && ratio >= 0.5)
{
// Use this one if it is the lowest width difference
if (diff < widthDiff)
{
widthDiff = diff;
found = resource;
scaleFactor =resource.size.height / designResolutionSize.height ;
CCLOG("Trying %s widthDiff %d ScaleFactor %.2f VisibleOffset %.0f, %.0f", found.directory, widthDiff, scaleFactor, director->getVisibleOrigin().x, director->getVisibleOrigin().y);
}
}
}
// so now we should have found which resource to use
searchPaths.push_back(found.directory);
Globals::resourcePath = found.directory;
CCLOG("Using %s widthDiff %d ScaleFactor %.2f VisibleOffset %.0f, %.0f", found.directory, widthDiff, scaleFactor, director->getVisibleOrigin().x, director->getVisibleOrigin().y);
director->setContentScaleFactor(scaleFactor);