如果做了一个游戏
并且AppDelegate中没有进行适配的
制作时窗口的大小设定为eglView->setFrameSize(1024, 728);
然后想把该程序移植到其他窗口大小不为(1024, 728)的设备上
做法如下
把层CCLayer 换成 CCSprite
设置该精灵的大小 this->setContentSize(CCSize(1024, 728));
默认的锚点是(0.5,0.5)
位置默认是(0,0)
这时画面就根据原点(0,0)布置
然后就是获取当前的界面大小, 设置该精灵位置为界面的中间
this->setPosition(ccp(origin.x + visibleSize.width/2, origin.y + visibleSize.height / 2));
这样设置之后无论移植到什么窗口大小的平台上都是居中显示
当是这样无法让该素材适应所有屏幕, 可能会太大, 可能会太小. 如果不想用全适应的话, 就应该用根据宽或根据高适应.
如果确定是根据宽还是根据高适应呢?
首先得到屏幕的长宽比currentAspectRatio和你现在开发游戏时原始长宽比originalAspectRatio。
if(currentAspectRatio>originalAspectRatio) 采用根据高度自适应
if(currentAspectRatio<originalAspectRatio) 采用根据宽度自适应
下面附上demo
#include "AppDelegate.h" #include "HelloWorldScene.h" USING_NS_CC; CCSize frameSize(1200, 300); CCSize resolutionSize(1000,800); AppDelegate::AppDelegate() { } AppDelegate::~AppDelegate() { } bool AppDelegate::applicationDidFinishLaunching() { // initialize director CCDirector* pDirector = CCDirector::sharedDirector(); CCEGLView* pEGLView = CCEGLView::sharedOpenGLView(); pEGLView->setFrameSize(frameSize.width, frameSize.height); pDirector->setOpenGLView(pEGLView); float currentAspectRatio = pDirector->getWinSize().width/pDirector->getWinSize().height; float originalAspectRatio = resolutionSize.width/resolutionSize.height; if(currentAspectRatio>originalAspectRatio)//采用根据宽度自适应 { pEGLView->setDesignResolutionSize(resolutionSize.width,resolutionSize.height,kResolutionFixedHeight ); } if(currentAspectRatio<=originalAspectRatio)// 采用根据长度自适应 { pEGLView->setDesignResolutionSize(resolutionSize.width,resolutionSize.height, kResolutionFixedWidth ); } // 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); // create a scene. it's an autorelease object CCScene *pScene = HelloWorld::scene(); // run pDirector->runWithScene(pScene); return true; } // This function will be called when the app is inactive. When comes a phone call,it's be invoked too void AppDelegate::applicationDidEnterBackground() { CCDirector::sharedDirector()->stopAnimation(); // if you use SimpleAudioEngine, it must be pause // SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic(); } // this function will be called when the app is active again void AppDelegate::applicationWillEnterForeground() { CCDirector::sharedDirector()->startAnimation(); // if you use SimpleAudioEngine, it must resume here // SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic(); }
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" USING_NS_CC; #define Point(x,y) stransforPosition(CCPoint(x,y)) extern CCSize FrameSize; extern CCSize resolutionSize; class HelloWorld : public cocos2d::CCSprite { public: // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::CCScene* scene(); // a selector callback void menuCloseCallback(CCObject* pSender); // implement the "static node()" method manually CREATE_FUNC(HelloWorld); float m_currentAndOrignalRatioX; float m_currentAndOrignalRatioY; cocos2d::CCPoint stransforPosition(cocos2d::CCPoint& pos) { cocos2d::CCPoint _point = pos-resolutionSize/2; CCEGLView* pEGLView = CCEGLView::sharedOpenGLView(); cocos2d::CCPoint _offset; switch (pEGLView->getResolutionPolicy()) { case kResolutionFixedHeight: { _offset = CCPoint (_point.x/m_currentAndOrignalRatioY*m_currentAndOrignalRatioX ,_point.y ); break; } case kResolutionFixedWidth: { _offset =CCPoint (_point.x ,_point.y/m_currentAndOrignalRatioX*m_currentAndOrignalRatioY ); break; } default: break; } return (resolutionSize/2 +_offset ); //return pos; } // { //CCSprite::setPosition(CCPoint(pos.x*m_currentAndOrignalRatioX, pos.y*m_currentAndOrignalRatioY)); //} }; #endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h" CCScene* HelloWorld::scene() { // 'scene' is an autorelease object CCScene *scene = CCScene::create(); // 'layer' is an autorelease object HelloWorld *layer = HelloWorld::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } // on "init" you need to initialize your instance bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !CCSprite::init() ) { return false; } CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin(); CCEGLView* pEGLView = CCEGLView::sharedOpenGLView(); pEGLView->getFrameSize(); CCSize _winSize = pEGLView->getFrameSize(); m_currentAndOrignalRatioX = _winSize.width/resolutionSize.width; m_currentAndOrignalRatioY = _winSize.height/resolutionSize.height; this->setContentSize(resolutionSize); this->setPosition(ccp(origin.x + visibleSize.width/2, origin.y + visibleSize.height / 2)); ///////////////////////////// // 2. add a menu item with "X" image, which is clicked to quit the program // you may modify it. // add a "close" icon to exit the progress. it's an autorelease object // add "HelloWorld" splash screen" CCSprite* pSprite = CCSprite::create("HelloWorld.png"); // position the sprite on the center of the screen pSprite->setPosition((Point(500, 400))); // add the sprite as a child to this layer this->addChild(pSprite, 0); for (int i = 0; i < 11; i++) { CCSprite* _sp = CCSprite::create("CloseNormal.png"); _sp->setPosition((Point(i*100, 800/2))); this->addChild(_sp); } for (int i = 0; i < 9; i++) { CCSprite* _sp = CCSprite::create("CloseNormal.png"); _sp->setPosition((Point(1000/2, i*100))); this->addChild(_sp); } return true; } void HelloWorld::menuCloseCallback(CCObject* pSender) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); #else CCDirector::sharedDirector()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif #endif }