之前做的都是橫版的遊戲,然後一般使用如下的代碼來適配多解析度:
typedef struct tagResource{ CCSize sizeInPixel; CCSize sizeDesign; char directory[100];}Resource;static Resource resPhone = { CCSizeMake(480, 320), CCSizeMake(480, 320), "iphone" };static Resource resPhoneRetina = { CCSizeMake(960, 640), CCSizeMake(480, 320), "iphonehd" };static Resource resPhone5Retina = { CCSizeMake(1136, 640), CCSizeMake(568, 320), "iphonehd" };static Resource resTable = { CCSizeMake(1024, 768), CCSizeMake(512, 384), "ipad" };static Resource resTableRetina = { CCSizeMake(2048, 1536), CCSizeMake(512, 384), "ipadhd" };
然後在 cocos的
bool AppDelegate::applicationDidFinishLaunching()函數中,通過如下的代碼來適配:
// initialize director CCDirector *pDirector = CCDirector::sharedDirector(); CCEGLView* pEGLView = CCEGLView::sharedOpenGLView(); pDirector->setOpenGLView(CCEGLView::sharedOpenGLView()); //設定素材目錄 CCSize frameSize = pEGLView->getFrameSize(); Resource actualResource; float actualHeight = fmin(frameSize.width, frameSize.height); float actualWidth = fmax(frameSize.width, frameSize.height); if (actualHeight > resTable.sizeInPixel.height) { actualResource = resTableRetina; } else if (actualHeight > resPhoneRetina.sizeInPixel.height) { actualResource = resTable; } else if (actualHeight > resPhone.sizeInPixel.height) { actualResource = resPhoneRetina; if (actualWidth > resPhoneRetina.sizeInPixel.width) { actualResource = resPhone5Retina; } } else { actualResource = resPhoneRetina; } CCFileUtils::sharedFileUtils()->setResourceDirectory(actualResource.directory); pDirector->setContentScaleFactor(1.0 *actualResource.sizeInPixel.height / actualResource.sizeDesign.height); // Set the design resolution pEGLView->setDesignResolutionSize(actualResource.sizeDesign.width, actualResource.sizeDesign.height, kResolutionNoBorder);
然後查了好久才發現原因:在於
setDesignResolutionSize 這個函數,先看看這個函數的實現:
m_obDesignResolutionSize.setSize(width, height);
m_fScaleX = (float)m_obScreenSize.width /
m_obDesignResolutionSize.width;
m_fScaleY = (float)m_obScreenSize.height /
m_obDesignResolutionSize.height;
這個是關鍵的代碼,這個代碼是將傳進去的第1,2個參數當作設計尺寸的width跟height,然後跟 screenSize的width,height分別求比值來確定縮放比例。
screenSize的 來源在哪,看到了2個函數
const CCSize&
CCEGLViewProtocol::getFrameSize() const
{
return
m_obScreenSize;
}
void CCEGLViewProtocol::setFrameSize(float width,
float height)
{
m_obDesignResolutionSize =
m_obScreenSize = CCSizeMake(width, height);
}
發現這個就是 跟
CCSize frameSize = pEGLView->getFrameSize();是一個size,即是這個frameSize,而frameSize是跟橫豎屏有關係的。
1. 如果是 橫屏,那frameSize的width跟height就是 960 * 640 , 剛好是 對應了 design這個結構體的width(480)跟height(320)兩個成員。
所以傳遞給 setDesignResolutionSize 的就依次是
actualResource.sizeDesign.width (值480) 跟actualResource.sizeDesign.height(值 320), 跟 960 * 640對應。
2. 如果是 豎屏,那麼frameSize的width跟height就是 640 * 960 ,對應的就是 design的 結構體的height(320)跟width(480)兩個成員。
所以傳遞給 setDesignResolutionSize就應該依次是
actualResource.sizeDesign.height(值 320) 跟actualResource.sizeDesign.width (值480),跟
640 * 960對應。
綜上,如果是橫屏,那麼應該使用如下的代碼:
// Set the design resolution pEGLView->setDesignResolutionSize(actualResource.sizeDesign.height, actualResource.sizeDesign.width, kResolutionNoBorder);