初学修改分辨率,可以参考TestCpp中的AppDelegate和main函数。在自己的项目中进行同样的修改。另外,画面布局时要用到相对坐标,可以参考TestCpp的VisibleRect。以上提到的函数可以参考本篇最后的代码。
你可以通过CCEGLView::sharedOpenGLView()->getFrameSize()方法来得到屏幕的真实分辨率大小。通过CCEGLView::sharedOpenGLView()->setFrameSize()设置屏幕真实分辨率大小,真实设备不需要进行该项设置。每个项目中的main.cpp可以进行此项设置。
DesignResolution是一个重要的概念,表示最完美显示的分辨率。设计分辨率是通过CCEGLView::sharedOpenGLView()->setDesignResolutionSize(width, height, policy)方法来设置的,第一,二个参数分别是设计分辨率的宽度和高度,第三个参数是你想要的模式。
pEGLView->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, kResolutionNoBorder);
cocos2d-x有提供两个多分辨率适配方案:
1. 尽量使用相对位置、坐标。
2. 按分辨率存放资源文件或者缩放图片资源,如下两个函数:
(1)多分辨率解决方案——非常简单,调用函数设置一个文件路径就行。缺少的文件,会转到默认的Resource下寻找。
CCFileUtils::sharedFileUtils()->setResourceDirectory("hd"); ——这一思路类似Android和IOS的分辨率方案 。hd是文件名,可以自定义,放在Resource下,把所需要的其它分辨率资源放到里面去。cocos2d-x自带例子:
D:\cocos2d-x\cocos2d-2.0-x-2.0.4\cocos2d-2.0-x-2.0.4\samples\TestCpp\Resources\hd
D:\cocos2d-x\cocos2d-2.0-x-2.0.4\cocos2d-2.0-x-2.0.4\samples\TestCpp\Resources\ipadhd
总结:调用函数之前,直接获取屏幕分辨率,区分大小。Resource是默认的480*320的路径,其它分辨率,得用同样的目录结构,放到独立的文件夹下。实践中,可以设定ipad,ipadmini等目录,存放不同分辨率的资源。
注意:如果独立文件夹hd下找不到需要的图片资源,就会到Resource目录下寻找。这样可以很方便地过滤掉一些不需要处理的图片,即只需要添加必须调整分辨率的图片到hd文件夹。
(2)pDirector->setContentScaleFactor(Resource.size.height/designResolutionSize.height);
——分为等比缩放和非等比缩放,缺点是图片可能会变模糊
模式——适配策略
现在cocos2d-x支持三种模式(kResolutionNoBorder、kResolutionShowAll、kResolutionExactFit)
Exact fit——非等比缩放,全屏显示,通过图片变形适配无黑边。
Show all——会选择高和宽中“小”的缩放因子(一般与缩放因子做乘法),进行等比缩放,因此有黑边。
No border——图形不变形,超出部分会被裁剪
当使用NoBorder模式的时候,有一些背景区域显示到屏幕以外去了。假如你使用绝对坐标在设计分辨率大小(480*320),你游戏的一些UI可能会显示不全。为了解决这个问题,你不得不设置这个坐标依据’visible rectangle’(可见矩形)的。你可以得到可见矩形的起点,通过CCDirector::sharedDirector()->getVisibleOrign()方法。调用CCDirector::sharedDirector()->getVisibleSize()方法你就可以确定屏幕上面的9个点, 左边,右边,上面,下面,中间,左上角,右上角,左下角,右下角。
假如你的游戏的所有坐标就是依靠这9个点,那么你的游戏就可以全屏展示了。
关于怎么计算这些点,你可以参考TestCpp项目里面的“VisibleRect”类。
关于三种模式的底层操作,可以见CCEGLViewProtocol.cpp代码
void CCEGLViewProtocol::setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy)
{
CCAssert(resolutionPolicy != kResolutionUnKnown, "should set resolutionPolicy");
if (width == 0.0f || height == 0.0f)
{
return;
}
m_obDesignResolutionSize.setSize(width, height);
m_fScaleX = (float)m_obScreenSize.width / m_obDesignResolutionSize.width;
m_fScaleY = (float)m_obScreenSize.height / m_obDesignResolutionSize.height;
if (resolutionPolicy == kResolutionNoBorder)
{
m_fScaleX = m_fScaleY = MAX(m_fScaleX, m_fScaleY);
}
if (resolutionPolicy == kResolutionShowAll)
{
m_fScaleX = m_fScaleY = MIN(m_fScaleX, m_fScaleY);
}
// calculate the rect of viewport
float viewPortW = m_obDesignResolutionSize.width * m_fScaleX;
float viewPortH = m_obDesignResolutionSize.height * m_fScaleY;
m_obViewPortRect.setRect((m_obScreenSize.width - viewPortW) / 2, (m_obScreenSize.height - viewPortH) / 2, viewPortW, viewPortH);
m_eResolutionPolicy = resolutionPolicy;
// reset director's member variables to fit visible rect
CCDirector::sharedDirector()->m_obWinSizeInPoints = getDesignResolutionSize();
CCDirector::sharedDirector()->createStatsLabel();
CCDirector::sharedDirector()->setGLDefaultValues();
}
cocos2d-x自带的Testcpp项目例子
Appdelegate中的代码 :可见有screenSize和designSize
bool AppDelegate::applicationDidFinishLaunching()
{
// initialize director
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
CCSize screenSize = CCEGLView::sharedOpenGLView()->getFrameSize();
CCSize designSize = CCSizeMake(480, 320);
if (screenSize.height > 320) //大于320就属于高清图片
{
CCSize resourceSize = CCSizeMake(960, 640); //这是iphone4的分辨率
CCFileUtils::sharedFileUtils()->setResourceDirectory("hd");
pDirector->setContentScaleFactor(resourceSize.height/designSize.height); //如果换高清图片,调整屏幕大小
}
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionNoBorder);
// turn on display FPS
pDirector->setDisplayStats(true);
// set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 / 60);
CCScene * pScene = CCScene::create();
CCLayer * pLayer = new TestController();
pLayer->autorelease();
pScene->addChild(pLayer);
pDirector->runWithScene(pScene);
return true;
}
可视区域代码如下,请参考
#ifndef __VISIBLERECT_H__
#define __VISIBLERECT_H__
#include "cocos2d.h"
USING_NS_CC;
class VisibleRect
{
public:
static CCRect getVisibleRect();
static CCPoint left();
static CCPoint right();
static CCPoint top();
static CCPoint bottom();
static CCPoint center();
static CCPoint leftTop();
static CCPoint rightTop();
static CCPoint leftBottom();
static CCPoint rightBottom();
private:
static void lazyInit();
static CCRect s_visibleRect;
};
#endif /* __VISIBLERECT_H__ */
#include "VisibleRect.h"
CCRect VisibleRect::s_visibleRect;
void VisibleRect::lazyInit()
{
if (s_visibleRect.size.width == 0.0f && s_visibleRect.size.height == 0.0f)
{
CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
s_visibleRect.origin = pEGLView->getVisibleOrigin();
s_visibleRect.size = pEGLView->getVisibleSize();
}
}
CCRect VisibleRect::getVisibleRect()
{
lazyInit();
return CCRectMake(s_visibleRect.origin.x, s_visibleRect.origin.y, s_visibleRect.size.width, s_visibleRect.size.height);
}
CCPoint VisibleRect::left()
{
lazyInit();
return ccp(s_visibleRect.origin.x, s_visibleRect.origin.y+s_visibleRect.size.height/2);
}
CCPoint VisibleRect::right()
{
lazyInit();
return ccp(s_visibleRect.origin.x+s_visibleRect.size.width, s_visibleRect.origin.y+s_visibleRect.size.height/2);
}
CCPoint VisibleRect::top()
{
lazyInit();
return ccp(s_visibleRect.origin.x+s_visibleRect.size.width/2, s_visibleRect.origin.y+s_visibleRect.size.height);
}
CCPoint VisibleRect::bottom()
{
lazyInit();
return ccp(s_visibleRect.origin.x+s_visibleRect.size.width/2, s_visibleRect.origin.y);
}
CCPoint VisibleRect::center()
{
lazyInit();
return ccp(s_visibleRect.origin.x+s_visibleRect.size.width/2, s_visibleRect.origin.y+s_visibleRect.size.height/2);
}
CCPoint VisibleRect::leftTop()
{
lazyInit();
return ccp(s_visibleRect.origin.x, s_visibleRect.origin.y+s_visibleRect.size.height);
}
CCPoint VisibleRect::rightTop()
{
lazyInit();
return ccp(s_visibleRect.origin.x+s_visibleRect.size.width, s_visibleRect.origin.y+s_visibleRect.size.height);
}
CCPoint VisibleRect::leftBottom()
{
lazyInit();
return s_visibleRect.origin;
}
CCPoint VisibleRect::rightBottom()
{
lazyInit();
return ccp(s_visibleRect.origin.x+s_visibleRect.size.width, s_visibleRect.origin.y);
}
参考
http://cocos2d-x.org/projects/cocos2d-x/wiki/Multi_resolution_support(multi-resolution support)
http://blog.csdn.net/visualcatsharp/article/details/8332411
http://blog.csdn.net/cen616899547/article/details/9084545
http://blog.csdn.net/zhangjingyangguang/article/details/7617816(前三篇是理论,这篇是实践。教我们怎么复用资源)