自适应写到一个节点中的好处就是,当你在一种屏幕下安排好布局之后,不论屏幕比例怎么变化,节点中的元素相对位置都不变。
屏幕自适应分为两种情况
m_winSize = CCDirector::sharedDirector()->getWinSize();
m_defaultSize =CCSize(default_winWidth,default_winHeight);
//log("winsize = %f,%f",m_winSize.width,m_winSize.height);
//log("defaultSize = %f,%f",m_defaultSize.width,m_defaultSize.height);
/**
* 获取缩放比例/不出屏幕缩放比例/出屏幕缩放比例
*/
m_fScaleX = m_winSize.width / m_defaultSize.width;//横向适应
m_fScaleY = m_winSize.height / m_defaultSize.height;//纵向适应
m_fWinRatio = m_winSize.width / m_winSize.height; //屏幕的宽 :屏幕的高
m_fDefaultRatio = m_defaultSize.width / m_defaultSize.height;//图片的宽: 图片的高
m_fScaleFit = m_fWinRatio > m_fDefaultRatio ? m_fScaleY :m_fScaleX;//屏幕内适应
m_fScaleFitReverse = m_fWinRatio > m_fDefaultRatio ? m_fScaleX :m_fScaleY;//屏幕外适应
}
void GameTools::scaleFullScreen(cocos2d::CCNode * _node){
_node->setScaleX(this->m_fScaleX);
_node->setScaleY(this->m_fScaleY);
}
void GameTools::scaleFitInScreen(cocos2d::CCNode *_node){
_node->setScale(this->m_fScaleFit);
}
void GameTools::scaleFitOutScreen(cocos2d::CCNode *_node){
_node->setScale(this->m_fScaleFitReverse);
}
//横向适应
void GameTools::scaleXScreen(cocos2d::CCNode *_node){
_node->setScale(this->m_fScaleX);
}
//纵向适应
void GameTools::scaleYScreen(cocos2d::CCNode *_node){
_node->setScale(this->m_fScaleY);
}
一、在屏幕中心的自适应,如背景图片、屏幕中图片:
要做到保持原比例,则不能分别使用setScaleX 和setScaleY。使用setScale()可以用原比例缩放图片。
要满足充满整个屏幕,则要保证图片图片无黑边。e.g. 屏幕的宽 :屏幕的高 >图片的宽: 图片的高,则setScale时用前者即宽的比例作为参数。此时,图片的高就会大于屏幕的高,所以图片会再y轴方向溢出屏幕。使用此方法一定要注意,不要给背景图片添加子节点,不然可能会溢出屏幕。
此时可以添加一个节点,给他设置默认宽高为图片的宽高,然后使用scaleFitOutScreen函数进行自适应,之后将背景图片添加到此节点中,坐标是相对于此节点的。
屏幕中图片使用scaleFitInScreen。此时图片不会溢出屏幕。
二、在屏幕四周的自适应,如按钮:
当需要在屏幕上添加多个控件,比如标签、图片等,并且要求不论采用什么设备,这些按钮总在屏幕的最左边、最右边、最上边、最下边。则可以创建一个节点,设置大小为(defaultSize.width,20),20这里是为了保证横向比纵向大很多,保证能横向拉满屏幕。再将节点贴到屏幕的最上边。对节点进行横向自适应。而其他控件则添加到节点中。此时,按钮就贴着屏幕的上边缘,并且进行了自适应。
举例:
//将图片贴着屏幕左下角放置
//新建Node,纵向拉满,并且使Node贴着屏幕左下角,在Node中添加图片。
CCNode* node = CCNode::create();
node->setContentSize(CCSize(20,default_winHeight));
node->setAnchorPoint(ccp(0,0.5));
node->setPosition(ccp(0,gWinSize.height/2));
this->addChild(node,300);
gToolsInstance->scaleYScreen(node);
CCSprite* spp1 = CCSprite::create("BuyIcon.png");
spp1->setPosition(ccp(0,0));
spp1->setAnchorPoint(ccp(0,0));
node->addChild(spp1,1);
//将图片贴着屏幕上边缘中间和右上角放置
//新建Node,横向拉满,并且使Node贴着屏幕上边缘。在Node中添加图片
CCNode* node2 = CCNode::create();
node2->setContentSize(CCSize(default_winWidth,20));
node2->setAnchorPoint(ccp(0.5,1));
node2->setPosition(ccp(gWinSize.width/2,gWinSize.height));
this->addChild(node2,300);
gToolsInstance->scaleXScreen(node2);
CCSprite* spp2 = CCSprite::create("BuyIcon.png");
spp2->setPosition(ccp(node2->getContentSize().width/2, node2->getContentSize().height));
spp2->setAnchorPoint(ccp(0.5,1));
node2->addChild(spp2,1);
CCSprite* spp3 = CCSprite::create("BuyIcon.png");
spp3->setPosition(ccp(node2->getContentSize().width, node2->getContentSize().height));
spp3->setAnchorPoint(ccp(1,1));
node2->addChild(spp3,1);
注意:m_defaultSize一般设为背景图片的大小,比如800*600,1366*768等。有一种特例情况,当给的图片比较小时,有想让图片X或者Y方向充满屏幕,则会失败。因为,当m_defaultSize和屏幕大小固定了以后,算出来的比例也就固定了。此时,在对图片进行缩放,则会使图片更小。这时候可以将图片加到this中,再使用
spTrack->setScale(gWinSize.width/spTrack->getContentSize().width)方法缩放。
需要注意的是Node的默认锚点为(0,0)、CCMenu添加时,一般不设置锚点,而只setPosition(CCPointZero)
多个地图需要在屏幕中滚动时,可以先设置一个节点,默认大小,进行屏幕外自适应。再在其中添加多个节点,节点大小设置为地图大小,拼接好,一起移动。