cocos2d-x屏幕分辨率,窗口大小总结

这个东西很烦人,相信很多人都不理解

今天来总结一下,首先有很多概念都要事先弄得清楚明白

1.屏幕分辨率

所谓屏幕分辨率相信很多人都知道他的概念,不就是1280pxX720PX吗?不就是这种形式吗?有什么难的,这几个词在各种手机评测上面不是已经用烂了吗?

可是很多人都没有真正理解这个概念!!!

1280pxX720px

它的意思是纵向1280个像素,横向720个像素。

记住!只是像素而已,和尺寸,和大小,和比例没有半毛钱的直接关系

我一直都以为为什么这个东西要叫做屏幕分辨率,为什么要叫做分辨率?之前一直觉得名不符实,一直以为像素不过是另一种度量单位,深受我们摄影老师的影响,误人子弟,现在想起来,真是naive!

记住,像素不是一种新的,类似cm,mm的单位,像素并不是一种计量长度的单位,至于他究竟是什么,对不起,无可奉告,自己看百度百科

可以知道的是:像素越密,清晰度越高

2.屏幕分辨率和屏幕尺寸

  先说说屏幕尺寸,这东西,才是我们直观感受到的东西,什么屏幕的大小啊,屏幕的尺寸啊,屏幕的比例啊,一切的一切都落在这个屏幕尺寸上,

  接下来就是干货了

  1.相同比例和大小的尺寸,屏幕上的像素分辨率越高,屏幕,越清晰!!!(这个足可以证明尺寸,大小和分辨率无关吧)

  2.同样的屏幕分辨率(比如1280pxX720px),用在不同的屏幕上,我们看到的效果天差地别!!!

  接下来进入正题!在游戏中是怎么做的!!

  接触过各种引擎或者直接做游戏的人应该都知道,在游戏中我们做游戏都是以像素作为单位的,比如,一张精灵的图片,100pxX30px,怎样处理呢?

  在windows平台是这样的,因为windows平台是窗口式程序,一个游戏程序可以设置它的窗口大小,也就是说,他的屏幕尺寸并不是固定的!!

  这个时候是分为两部分处理的:

      1.设置窗口的大小:长宽;这一步相当于人为地规定了屏幕的尺寸(以像素的形式)

      2.设置设计尺寸:根据各种手段,使精灵图片适配窗口的大小

  而在移动端,包括安卓端和苹果端:因为并不是窗口式的OS,事实上就那么点屏幕,也做不了窗口式的OS,所以屏幕并不可更改所以只有一个步骤:

      设置设计尺寸:根据各种手段,使屏幕适配窗口的大小

好,解决方案就是以上两种思想,我来仔细解释一下,我们知道,因为各种电脑,各种手机,尺寸都不一样,分辨率也他妈不一样,这对于开发者来说是一个很复杂的问题,你想想,不同的尺寸,市面上真是数不胜数,我们怎么办呢?

好,开发者决定以像素为单位,进行开发,这个方法不错,毕竟各种图片,纹理,都是以像素为单位的

,可是相同的像素大小,也就是相同的分辨率,在不同平台上的尺寸都不一样,比如说,同样是960pxX720px,在这个手机上也许尺寸更大一些,那个手机上,也许尺寸更小一些?我们怎么紧紧跟随尺寸呢?毕竟,尺寸和分辨率是两回事啊!!

这个任务实际上是交给手机厂商的!!怎么样?是不是有一种很爽的感觉!!,这就是产业链啊!!!以前总在知乎上看他们辩论产业链优势,现在终于体会到了,对于厂商来说,分辨率就是写上去的事儿,很简单,可是解决了我们一个大麻烦,这样,对于我们来说,从手机设备厂商上获得的分辨率,就是尺寸啊!!!!  他在逻辑上并不是尺寸,但是这并不妨碍我们把他当作尺寸来看待!!!!

好了,有了以上的解释,

  对于PC端:第一步设置窗口大小的时候,实际上可以认为我们是在认为设置安卓手机的大小尺寸,怎么样,是不是有一种很吊的感觉!!!模仿手机端,我们是以像素来代替尺寸

  第二步的处理接下来在手机端一起讲

  对于安卓端:

      第一步对于安卓端来说不用考虑。

      第二步:获得固定的尺寸分辨率(自己发明的:即可以代表尺寸的分辨率):这一步对于开发者来说是透明的,也就是说,开发者这一步并不知道 具体的分辨率是多少,系统会自动给与

      记作ScreenX和ScreenY

      开发者自定义一个尺寸,我们称之为设计尺寸,仍然以像素为单位,记作designX和designY

      scaleX=ScreenX/designX

      scaleY=ScreenY/designY

      然后就选择适配方式:

        有铺满屏幕:那就用scaleXxdesignX,scaleYXdesignY来获得实际的尺寸,注意在这个过程中,场景中的精灵等等都这样变换,也就是说,游戏场景可能会变形得比较厉害

        有保持比例而且不超出屏幕:也就是保持比例不变形且不对素材进行裁剪:实现的时候是对选择scaleX和scaleY中较小的一个作为缩放因子,对designX和designY进行缩放

        有保持比例而且不留空白:也就是保持比例不变形,且充分利用屏幕的每个空间:实现的时候是对选择scaleX和scaleY中较大的一个作为缩放因子,对designX和designY进行缩放

        有保持比例且按照宽度铺满屏幕:也就是保持比例不变形,且让宽度刚好铺满屏幕,实现的时候用scaleX作为缩放因子,对designX和designY进行缩放

        有保持比例且按照高度度铺满屏幕:也就是保持比例不变形,且让宽度刚好铺满屏幕,实现的时候用scaleY作为缩放因子,对designX和designY进行缩放

总结一下,后四种其实是一种类似的思想,

终于把理论部分说完了,感觉上面讲完了,cocos2d-x里面的也没有什么讲的了,cocos里面的思想和这个就是一样的,

直接上函数

glview->setDesignResolutionSize(720,1280,ResolutionPolicy::SHOW_ALL);

  这个函数其实就是第二步骤的完整函数,这个前一部分指定我们设计游戏的时候用的尺寸分辨率,然后后面的就是适配风格了

怎么实现这种适配风格可以看看源码

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();
}

  这个是setDesignResolutionsize函数,可以看到,通过参数指定了私有成员_designResolutionSize的值,这个就是设计分辨率!!但是注意一下,opengl创建窗口的时候(请原谅我用窗口这个词),并不是以设计尺寸分辨率创建的,

  可以看到,这个函数里只是指定了设计尺寸和适配风格,并没有实现适配风格,可以猜一下,实现应该封装在updateDesignResoltionSize里了,进去看看

void GLView::updateDesignResolutionSize()
{
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
float viewPortW = _designResolutionSize.width * _scaleX;
float viewPortH = _designResolutionSize.height * _scaleY; _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->_isStatusLabelUpdated = true;
director->setGLDefaultValues();
}
}

  

可以看到,这个里面实现了上面讲的那些适配风格的适配方法

看到这里,我们应该大体能猜到,最终创建的窗口应该是那个叫做_viewPortRect的东西,好了,屏幕适配就写到这里了,今天状态不好,从今天起,决定戒掉小说,OK!

今天更新一下,主要是最近自己的项目中间出现一个非常麻烦的问题,今天终于解决了,关于触摸响应位置不准确的问题,其实主要是windows平台上设置产生的窗口大小超过了PC的物理尺寸大小!!!

详细的解释见下面的链接

触摸位置不准确

上一篇:Android Studio:You need to use a Theme.AppCompat theme (or descendant) with this activity. AlertDialog


下一篇:elasticsearch与mongodb分布式集群环境下数据同步