Using sprite atlases in a multi resolution setup in Cocos2D-x

瘦欲@ 提交于 2020-03-05 07:24:27

问题


I've just been able to setup a Cocos2d-x for a multiresolution environment. Ie supporting all/most of the available iPhone screen sizes.

My next step is to scrap the individual files (bunch of pngs) and use sprite atlases (aka sprite sheets) instead.

How does this work in Cocos2D-x? Does anyone have a working sample setup?

Once again, Google and existing documentation (well, I don't think that exists) fail me.


回答1:


For cocos2d-x v3.5...

The cocos2d-x test classes are always a great place to look to see how things can be done with cocos2d-x.

Check out the AppDelegate.cpp in: Cocos2d-x/cocos2d-x-3.5/tests/cpp-tests/Classes/AppDelegate.cpp.

In that class the window size is tested to see which set of assets should be loaded. That is part of the issue, deciding which assets to load.

For iOS retina, you can check the size of the screen and then set the content scale factor to either 1.0 for standard resolution or 2.0 for retina resolution. Unfortunately, cocos2d-x doesn't seem to ever detect certain screen sizes and call Director::getInstanct()->setContentScaleFactor(2.0) for you, so I think we have to do this our self.

I have not tested the impact of setting contentScaleFactor on non-apple devices yet...

Check out the code below. Try running it in your AppDelegate::applicationDidFinishLaunching() method to get an idea of how cocos2d-x sees screen pixels and points; the result is not exactly what I expected. The output below is for an iPhone 5 device.

director->setContentScaleFactor(2);
Size winSizePoints = director->getWinSize();
Size winSizePixels = director->getWinSizeInPixels();
Size visibleSize = director->getVisibleSize();

CCLOG("Content scale factor set to 2.0.");
CCLOG("winSizePoints:%.2f,%.2f", winSizePoints.width, winSizePoints.height);
CCLOG("winSizePixels:%.2f,%.2f", winSizePixels.width, winSizePixels.height);
CCLOG("visibleSize:%.2f,%.2f", visibleSize.width, visibleSize.height);

director->setContentScaleFactor(1);
winSizePoints = director->getWinSize();
winSizePixels = director->getWinSizeInPixels();
visibleSize = director->getVisibleSize();
CCLOG("Content scale factor set to 1.0.");
CCLOG("winSizePoints:%.2f,%.2f", winSizePoints.width, winSizePoints.height);
CCLOG("winSizePixels:%.2f,%.2f", winSizePixels.width, winSizePixels.height);
CCLOG("visibleSize:%.2f,%.2f", visibleSize.width, visibleSize.height);

Output of above code:

Content scale factor set to 2.0.

winSizePoints:1136.00,640.00

winSizePixels:2272.00,1280.00

visibleSize:1136.00,640.00

Content scale factor set to 1.0.

winSizePoints:1136.00,640.00

winSizePixels:1136.00,640.00

visibleSize:1136.00,640.00

So it seems we have to check the the screen size and then choose assets.

One option is to then use code like this to decide which assets to load based on if the screen is retina or not. You could use a similar approach to also loading different size background images to deal with different aspect ratios (more aspect ratios below).

float scaleFactor = CCDirector::getInstance()->getContentScaleFactor();
if (scaleFactor > 1.99)
{
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("spriteSheet-hd.plist", "spriteSheet-hd.png");
}
else
{
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("spriteSheet.png", "spriteSheet.plist");
}

For sprite sheets, I highly recommend Texture Packer. Awesome tool that can create SD and HD sheets and .plist files for you with the press of one button.

If you publish to multiple platforms, you will also want to use the macros to detect the device type and use that information in deciding which assets to load. e.g.

if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)

elif CC_TARGET_PLATFORM == CC_PLATFORM_WP8

elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID

elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS

elif CC_TARGET_PLATFORM == CC_PLATFORM_MAC)

endif

Another thing to consider is that on low power CPU and RAM devices, loading large assets might make your frames per second (FPS) go to crap. Or worse, the device might not be able to load the asset or could crash the game. So be sure to test/profile on least common denominator devices that you plan to support.

Aspect Ration is another important issue (landscape width:height). iPad aspect ratio is 4:3 iPhone 4 is 3:2 iPhone 5 & 6 are 16:9 Android throws in a bunch more width:height ratios. WP8.1 is 15:9... not sure if others.

The point is that you probably don't want to stretch your backgrounds to get them to fill the screen, or have black bars on the edges where assets are not tall or wide enough.

To deal with this I create background assets that are wider than they need to be going off the right side of the screen. That content looks good but is not vital to convey the meaning of the background. That extra content can be clipped on devices that have narrower aspect ratios, i.e. ipad, and is visible on wider aspect ratio devices, i.e. iPhone 6. The background images are then scaled up/down to match the screenSize height and retain their aspect ratio.



来源:https://stackoverflow.com/questions/29786958/using-sprite-atlases-in-a-multi-resolution-setup-in-cocos2d-x

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!