zoukankan      html  css  js  c++  java
  • Cocos2d-x 3.1 一步一步地做改编

    本文并不想谈论的屏幕改编或真理的概念。假设不知道cocos2d-x的,请先看这篇文章:http://www.cocoachina.com/gamedev/cocos/2014/0516/8451.html。本文有一些内容和图片是引用这篇文章的。看了那么多网上关于屏幕适配的文章,还是认为似懂非懂。所以最好的方法就是自己一步步做好适配。


    一、依据屏幕尺寸选择“最”合适的图片。

    假设依据屏幕尺寸来选择一样大小的图片,那么美工要哭了,由于对于安卓机,各种各样的分辨率啊。不仅美工要哭了,程序猿也要哭了。所以,我们仅仅能选择最合适的图片,比方320*500分辨率和300*480分辨率的屏幕能够使用320*480的图片。


    1、在Cocos2d-x自带的解决方式中就有针对iphone、ipad和ipadhd所做的适配方案。在projectcpp-empty-test有样例。

    // AppMacros.h
    #define DESIGN_RESOLUTION_480X320    0
    #define DESIGN_RESOLUTION_1024X768   1
    #define DESIGN_RESOLUTION_2048X1536  2
    
    // 要切换设计方案,改变这一行就可以
    #define TARGET_DESIGN_RESOLUTION_SIZE  DESIGN_RESOLUTION_480X320
    
    typedef struct tagResource
    {
        cocos2d::Size size;		// 尺寸
        char directory[100];	// 资源路径
    }Resource;
    
    static Resource smallResource  =  { cocos2d::Size(480, 320),   "iphone" };
    static Resource mediumResource =  { cocos2d::Size(1024, 768),  "ipad"   };
    static Resource largeResource  =  { cocos2d::Size(2048, 1536), "ipadhd" };
    
    #if (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_480X320)
    static cocos2d::Size designResolutionSize = cocos2d::Size(480, 320);
    #elif (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_1024X768)
    static cocos2d::Size designResolutionSize = cocos2d::Size(1024, 768);
    #elif (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_2048X1536)
    static cocos2d::Size designResolutionSize = cocos2d::Size(2048, 1536);
    #else
    #error unknown target design resolution!
    #endif
    
    // 480*320的字体大小是24号,依据当前的分辨率来改动字体大小
    #define TITLE_FONT_SIZE  (cocos2d::Director::getInstance()->getOpenGLView()->getDesignResolutionSize().width / smallResource.size.width * 24)

    从上面能够看出,cocos2d-x定义了三种大小,各自是iphone(480*320),ipad(1024*768),ipadhd(2048*1536),一般用得比較多的是iphone和ipad。

    我们再看一下资源目录。project->Resource下:



    iphone文件夹:



    ipad文件夹:



    ipadhd文件夹:


    也就是说。在这三个目录里面有三套不同大小分辨率的图片,我们之后依据屏幕大小来选择相应的图片即可了。


    2、实现怎么依据屏幕大小来选择图片。

    新建一个project。再将AppMacros.h文件拷贝过去。

    // AppDelegate.cpp
    bool AppDelegate::applicationDidFinishLaunching() {
        // initialize director
        auto director = Director::getInstance();
        auto glview = director->getOpenGLView();
        if(!glview) {
            glview = GLView::create("My Game");
    		glview->setFrameSize(480, 320);	// 在这里设置创建窗体的尺寸,手机上这个就不用啦,由于手机有固定的屏幕
            director->setOpenGLView(glview);
        }
    
    	auto screenSize = glview->getFrameSize();	// 获取屏幕尺寸
    	std::vector<std::string> searchPaths;
    
    	// 这里是实现的重点。比較屏幕的高和设定的三种适配尺寸的高。选择合适的图片
    	// 然后将相应图片的路径加入到搜索路径中,那么cocos2d-x就会到该文件夹去寻找图片
    	if (screenSize.height > middleResource.size.height)
    	{
    		searchPaths.push_back(largeResource.directory);
    	}else if (screenSize.height > smallResource.size.height)
    	{
    		searchPaths.push_back(middleResource.directory);
    	}else
    	{
    		searchPaths.push_back(smallResource.directory);
    	}
    	
    	FileUtils::getInstance()->setSearchPaths(searchPaths);
    
        // 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);
    
        // create a scene. it's an autorelease object
        auto scene = HelloWorld::createScene();
    
        // run
        director->runWithScene(scene);
    
        return true;
    }


    3、改变窗体尺寸来看效果:

    窗体尺寸500*300:

    由于高300小于320,所以使用480*320的图片。这时候看到的是左右有黑边,上下被截了一点。

    没事,以下会讲怎么解决。


    窗体尺寸700*300:

    还是用480*320分辨率的,都是300的错。


    窗体尺寸800*480:


    这次用的是1024*768的了。由于320<480<768。


    在500*300尺寸中我们看到图片左右由于不够宽而出现黑边,而上下由于太大了而被截取了一部分。那么要怎么解决问题呢?往下看。




    二、图片与屏幕“完美”融合

    为了使图片能与屏幕“完美”融合。Cocos2d-x提供了一组相关的接口和5种分辨率适配的策略。

    首先了解一下三种分辨率:

    资源分辨率:也就是图片分辨率。以下宽Resource Width简写为RW,高Resource Height简写为RH。

    设计分辨率:也就是我们设定区域的分辨率,以下宽Design Width简写为DW。高Design Height简写为DH。

    屏幕分辨率:也就是窗体分辨率,以下宽Screen Width简写为SW,高Screen Height简写为SH。


    Cocos2d-x的图片显示有以下两个过程:

    从资源分辨率到设计分辨率,从设计分辨率到屏幕分辨率。



    这个过程就是:

    1、先选定目标的设计分辨率,在AppMacros.h中我们定义了三种分辨率,各自是480*320,1024*768,2048*1536:


    默认选中的是480*320:



    2、从资源分辨率到设计分辨率

    通过setContentScaleFactor()函数来缩放图片的分辨率。以适应设计分辨率的大小。

    这个函数的參数不是通过资源宽/屏幕宽、资源高/屏幕高得来的,而是通过资源宽/设计分辨率宽、资源高/设计分辨率高得来的。这样我们就能够不关注屏幕尺寸,先依据现有的资源跟选好的设计分辨率来做好适配。

    在上面800*480尺寸的图中能够看到,图片四边都被截取了,原因就是没有做好图片的缩放,接下来我们先用setContentScaleFactor()来做图片缩放。

    设计分辨率选择的是480*320,窗体分辨率480*321,这样用的就是1024*768分辨率的图片了:

    	if (screenSize.height > middleResource.size.height)
    	{
    		searchPaths.push_back(largeResource.directory);
    		director->setContentScaleFactor(largeResource.size.height/designResolutionSize.height);
    	}else if (screenSize.height > smallResource.size.height)
    	{
    		searchPaths.push_back(middleResource.directory);
    		// 缩放因子是资源宽/设计分辨率宽
    		director->setContentScaleFactor(middleResource.size.height/designResolutionSize.height);	
    	}else
    	{
    		searchPaths.push_back(smallResource.directory);
    		director->setContentScaleFactor(smallResource.size.height/designResolutionSize.height);
    	}

    效果:


    用高度比作为内容缩放因子,保证了背景资源的垂直方向在设计分辨率范围内的所有显示。


    改动缩放因子为资源宽/设计宽:

    // 缩放因子是资源宽/设计分辨率宽
    director->setContentScaleFactor(middleResource.size.width/designResolutionSize.width);


    用宽度比作为内容缩放因子。保证了背景资源的水平方向在设计分辨率范围内的所有显示。


    能够參考一下这张图。我的是横屏的,这张图画的是竖屏的,只是原理一样:



    3、从设计分辨率到屏幕分辨率

    设计分辨率是我们自己定义分辨率方案。图片依据设计分辨率做好了缩放效果了,假设跟屏幕分辨率适配,说白了就是一厢情愿。最后一步就是使用setDesignResolutionSize()函数来实现设计分辨率到屏幕分辨率的完美适配了:

    void GLViewProtocol::setDesignResolutionSize(float width,	// DW
    											 float height,	// DH
    											 ResolutionPolicy resolutionPolicy)	// 适配策略
    五种适配策略:

    enum class ResolutionPolicy
    {
        EXACT_FIT,
        NO_BORDER,
        SHOW_ALL,
        FIXED_HEIGHT,
        FIXED_WIDTH,
    
        UNKNOWN,
    };


    先看不使用适配策略的情况。在第2中,设置窗体分辨率为960*640:


    接着,我们使用setDesignResolutionSize()函数来适配设计分辨率和屏幕分辨率:

    glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::EXACT_FIT);


    效果:

    这时候就是我们想要的效果了。




    上面说到共同拥有五种分辨率适配的策略。事实上就是从设计分辨率适配到屏幕分辨率时,图片拉伸的策略:

    1、ResolutionPolicy::SHOW_ALL

    屏幕宽、高分别和设计分辨率宽、高计算缩放因子,取较(小)者作为宽、高的缩放因子。保证了设计区域所有显示到屏幕上,但可能会有黑边。

    2、ResolutionPolicy::EXACT_FIT

    屏幕宽 与 设计宽比 作为X方向的缩放因子,屏幕高 与 设计高比 作为Y方向的缩放因子。

    保证了设计区域全然铺满屏幕,可是可能会出现图像拉伸。


    3、ResolutionPolicy::NO_BORDER

    屏幕宽、高分别和设计分辨率宽、高计算缩放因子,取较(大)者作为宽、高的缩放因子。

    保证了设计区域总能一个方向上铺满屏幕,而还有一个方向通常会超出屏幕区域。

    如图:


    ResolutionPolicy::NO_BORDER是之前官方推荐使用的方案,他没有拉伸图像,同一时候在一个方向上撑满了屏幕,可是新增加的两种策略将撼动ResolutionPolicy::NO_BORDER的地位。

    ResolutionPolicy::FIXED_HEIGHT和ResolutionPolicy::FIXED_WIDTH都是会在内部修正传入设计分辨率。以保证屏幕分辨率到设计分辨率无拉伸铺满屏幕。

    4、ResolutionPolicy::FIXED_HEIGHT

    保持传入的设计分辨率高度不变,依据屏幕分辨率修正设计分辨率的宽度。

    适合高方向须要撑满,宽方向可裁减的游戏,结合setContentScaleFactor(RH/DH)使用。


    5、ResolutionPolicy::FIXED_WIDTH

    保持传入的设计分辨率宽度不变,依据屏幕分辨率修正设计分辨率的高度。

    适合宽方向须要撑满,高方向可裁减的游戏,结合setContentScaleFactor(RW/DW)使用。


    如图:


    屏幕适配的就说到这里了,因为本人口才不好,所以有些地方可能表达不够清晰,请见谅。

    网上讲屏幕适配这方面的文章一搜一大把,但都是理论知识,个人认为最好的学习方法是做一个demo,不要一步一步,怎么看效果,这种把握能力。

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    BF算法和KMP算法
    Python课程笔记 (五)
    0268. Missing Number (E)
    0009. Palindrome Number (E)
    0008. String to Integer (atoi) (M)
    0213. House Robber II (M)
    0198. House Robber (E)
    0187. Repeated DNA Sequences (M)
    0007. Reverse Integer (E)
    0006. ZigZag Conversion (M)
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4727117.html
Copyright © 2011-2022 走看看