17【cocos2d-x 源码分析】:多分辨率支持的详细分析

对应源码位置:cocos2d-x-3.3\cocos\platform\GLView

设计分辨率与屏幕分辨率

cocos2d-x中,进行游戏设计时使用逻辑上的设计分辨率,当具体游戏运行在物理机上时对应具体屏幕的分辨率,这就存在从设计分辨率到具体屏幕分辨率的适配问题,主要有一系列的适配策略,这里暂不列举,但就源码进行分析,一目了然。

//这里设置 设计分辨率的大小  并指定 设计分辨率的策略
void GLView::setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy)
{
    CCASSERT(resolutionPolicy != ResolutionPolicy::UNKNOWN, "should set resolutionPolicy");
    
    if (width == 0.0f || height == 0.0f)
    {
        return;
    }
	//设置相应属性
    _designResolutionSize.setSize(width, height);
    _resolutionPolicy = resolutionPolicy;
    //更新配置 关键部分·
    updateDesignResolutionSize();
 }
void GLView::updateDesignResolutionSize()
{
	//_screenSize 是指实际对应的 物理屏幕宽高
	//第一个if 是保证数据符合逻辑
    if (_screenSize.width > 0 && _screenSize.height > 0
        && _designResolutionSize.width > 0 && _designResolutionSize.height > 0)
    {	
    	
    	//物理屏幕分辨率 与 设计分辨率 的缩放比
        _scaleX = (float)_screenSize.width / _designResolutionSize.width;
        _scaleY = (float)_screenSize.height / _designResolutionSize.height;
        
        // 如果不满足 下面的适配策略  就相当于 使用不等比缩放 而全屏
        
        //下面是最精彩的部分  就算看这几个 适配策略看不明白  一看源码 
        //就再明白不过了
        //如果   等比且全屏 所以取两个缩放比较大的
        if (_resolutionPolicy == ResolutionPolicy::NO_BORDER)
        {
            _scaleX = _scaleY = MAX(_scaleX, _scaleY);
        }
        //只要有一个边 达到屏幕大小 就不在缩放 所以选小的  这可能导致出现黑边  
        else if (_resolutionPolicy == ResolutionPolicy::SHOW_ALL)
        {
            _scaleX = _scaleY = MIN(_scaleX, _scaleY);
        }
        //固定高,拉伸宽,使得跟设备高宽比一样,最后再全屏显示。
        else if ( _resolutionPolicy == ResolutionPolicy::FIXED_HEIGHT) {
            _scaleX = _scaleY;
            //宽度修正 为了实现全屏
            _designResolutionSize.width = ceilf(_screenSize.width/_scaleX);
        }
          //固定宽,拉伸高,使得跟设备高宽比一样,最后再全屏显示
        else if ( _resolutionPolicy == ResolutionPolicy::FIXED_WIDTH) {
            _scaleY = _scaleX;
             //高度修正 为了实现全屏
            _designResolutionSize.height = ceilf(_screenSize.height/_scaleY);
        }
        
        // calculate the rect of viewport
        //从而 计算出 视口大小 即为opengl绘制的窗口
        float viewPortW = _designResolutionSize.width * _scaleX;
        float viewPortH = _designResolutionSize.height * _scaleY;
        //注意 前两个参数 相减并除2 是为了保证opengl绘制的区域的起点在合适的位置
        //即为 让整个绘制区域在屏幕居中
        _viewPortRect.setRect((_screenSize.width - viewPortW) / 2, (_screenSize.height - viewPortH) / 2, viewPortW, viewPortH);
        
        // reset director's member variables to fit visible rect
        auto director = Director::getInstance();
        director->_winSizeInPoints = getDesignResolutionSize();
        director->createStatsLabel();
        director->setGLDefaultValues();
    }
}

资源分辨率

当根据纹理的大小来确定Node的大小时,资源分辨率的设置就是用来计算纹理大小到Node内容的换算比率。大致如此,不再细说。

void Director::setContentScaleFactor(float);
Size Texture2D::getContentSize() const
{
	Size size;
	size.width=_contentSize.width/CC_CONTENT_SCALE_FACTOR;
	size.height=_contentSize.height/CC_CONTENT_SCALE_FACTOR;
	return size;
}

最后

本系列内容基本结束,目前还有 物理引擎脚本系统未分析,由于该部分非源码部分,而是对第三方的集成,后续以项目实例的方式介绍。

你可能感兴趣的:(cocos2d-x,c++,cocos2d-x,源码分析)