cocos2d-x 多分辨率设定

初学修改分辨率,可以参考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(前三篇是理论,这篇是实践。教我们怎么复用资源)


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值