cocos2d-x 屏幕自适应解决办法

转自:http://blog.csdn.net/zhangjingyangguang/article/details/7617816

 

最近在写一个项目,要求pc,ipad,andriod平台上都可以运行,所以选择用cocos2d-x来开发。我们的资源大小是1024*768的,在pc上和苹果上都是没有问题的,可是到了andriod上,问题就来了。andriod上有有各种各样的分辨率,那么程序在所有的分辨率上都可以正常运行显示呢?针对这个问题,我想了好几种方法:

(1)弄多套资源

因为这个项目里面有很多动画资源,如果要弄多套资源,工作量比较大,项目时间比较紧,不允许用这套方案

(2)cocos2d-x里面有一个方法

pDirector->setContentScaleFactor(0.5);

这个方法是把整个场景缩小到一半,界面上看上去没问题,但是里面要点击的精灵相应位置全不对了,如果用这套方法,代码要写好几套,要根据不同的分辨率来调整不同精灵的摆放位置和相应位置。尽管资源是一份,可是,代码要重新写过,要先机器的分辨率,然后再决定用那套精灵位置和相应位置的代码。可如何或如andriod下面机器分分辨率,这个还是个问题。再三思考后,打算做成多个apk文件,就做主流的分辨率,譬如说1024*768,1280*800,800*480等。本来已经打算这么弄了,可还是发现了更好的第三种办法。

(3)这种办法只需要一套资源,精灵位置也只有一套(不管是绝对位置还是相对位置),绝对是最佳的选择。

先说windows下的解决方法:

譬如说我们的项目是1024*768的,现在要改成大小是800*600的,那么只需要写一个函数

[cpp]  view plain copy
  1. int ViewAutoScale(cocos2d::CCEGLView* view,
  2. void* title,
  3. int width,
  4. int height,
  5. cocos2d::CCSize* supportDisplay,
  6. int displays,
  7. int defaultWidth,
  8. int defaultHeight)
  9. {
  10. if(view == NULL)
  11. {
  12. return -1;
  13. }
  14. for (int i=0; i < displays; i++)
  15. {
  16. if ((w==size.width && h==size.height) || (h==size.width && w==size.height))
  17. {
  18. view->Create((LPCTSTR)title, width, height);
  19. return i+1;
  20. }
  21. }
  22. view->Create((LPCTSTR)title, defaultWidth, defaultHeight);
  23. view->setScreenScale(min((float)width/ defaultWidth, (float)height/ defaultHeight));
  24. view->resize(width, height);
  25. view->centerWindow();
  26. return 0;
  27. }
[cpp]  view plain copy
  1. int ViewAutoScale(cocos2d::CCEGLView* view,     
  2.                       void* title,    
  3.                       int width,     
  4.                       int height,    
  5.                       cocos2d::CCSize* supportDisplay,    
  6.                       int displays,    
  7.                       int defaultWidth,    
  8.                       int defaultHeight)    
  9.     {    
  10.          if(view == NULL)    
  11.         {    
  12.                  return -1;    
  13.         }    
  14.         for (int i=0; i < displays; i++)    
  15.         {    
  16.   
  17.   
  18.             if ((w==size.width && h==size.height) || (h==size.width && w==size.height))    
  19.                 {    
  20.                      view->Create((LPCTSTR)title, width, height);    
  21.                              return i+1;    
  22.                 }    
  23.         }    
  24.         view->Create((LPCTSTR)title, defaultWidth, defaultHeight);    
  25.         view->setScreenScale(min((float)width/ defaultWidth, (float)height/ defaultHeight));    
  26.         view->resize(width, height);    
  27.         view->centerWindow();    
  28.         return 0;    
  29.     }    


这个函数要放在AppDelegate.cpp中作为全局函数,然后在

bool AppDelegate::initInstance()中调用,用法如下:

[cpp]  view plain copy
  1. bool AppDelegate::initInstance()
  2. {
  3. bool bRet = false;
  4. do
  5. {
  6. #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
  7. // Initialize OpenGLView instance, that release by CCDirector when application terminate.
  8. // The HelloWorld is designed as HVGA.
  9. CCSize sSupportDisplay[]={CCSize(1024, 768)};
  10. CCEGLView * pMainWnd = new CCEGLView();
  11. //CC_BREAK_IF(! pMainWnd
  12. // || ! pMainWnd->Create(TEXT("回乡偶书"), 1024, 768));
  13. if (ViewAutoScale(pMainWnd,TEXT("回乡偶书"),1024,768,
  14. sSupportDisplay,
  15. sizeof(sSupportDisplay)/sizeof(CCSize),
  16. 1024,
  17. 768)<0)
  18. {
  19. return false;
  20. }
  21. #endif // CC_PLATFORM_WIN32
[cpp]  view plain copy
  1. bool AppDelegate::initInstance()  
  2. {  
  3.     bool bRet = false;  
  4.     do  
  5.     {  
  6. #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)  
  7.   
  8.         // Initialize OpenGLView instance, that release by CCDirector when application terminate.  
  9.         // The HelloWorld is designed as HVGA.  
  10.         CCSize sSupportDisplay[]={CCSize(1024, 768)};  
  11.         CCEGLView * pMainWnd = new CCEGLView();  
  12.         //CC_BREAK_IF(! pMainWnd  
  13.         //      || ! pMainWnd->Create(TEXT("回乡偶书"), 1024, 768));  
  14.         if (ViewAutoScale(pMainWnd,TEXT("回乡偶书"),1024,768,  
  15.                             sSupportDisplay,  
  16.                             sizeof(sSupportDisplay)/sizeof(CCSize),  
  17.                             1024,  
  18.                             768)<0)  
  19.         {  
  20.             return false;  
  21.         }  
  22.   
  23. #endif  // CC_PLATFORM_WIN32  

}

上面的1024*768是我们本身的大小,800*480是我们想适应的大小,这样,就只要调整800*480的参数,就可以改成自己想要的大小。

第二个是在andriod下实现屏幕自适应,其实更简单,只需要一个方法,而且cocos2d-x下面已经帮我们实现好了,只需要调用即可。

修改方法如下:

进入到HelloWorld/android/jni/helloworld/main.cpp中,

然后调用view->create(1024,768);

代码如下:

[cpp]  view plain copy
  1. void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)
  2. {
  3. if (!cocos2d::CCDirector::sharedDirector()->getOpenGLView())
  4. {
  5. cocos2d::CCEGLView *view = &cocos2d::CCEGLView::sharedOpenGLView();
  6. view->setFrameWidthAndHeight(w, h);
  7. view->create(1024,768);
  8. // if you want to run in WVGA with HVGA resource, set it
  9. // view->create(480, 320); Please change it to (320, 480) if you're in portrait mode.
  10. cocos2d::CCDirector::sharedDirector()->setOpenGLView(view);
  11. AppDelegate *pAppDelegate = new AppDelegate();
  12. cocos2d::CCApplication::sharedApplication().run();
  13. }
  14. else
  15. {
  16. cocos2d::CCTextureCache::reloadAllTextures();
  17. cocos2d::CCDirector::sharedDirector()->setGLDefaultValues();
  18. }
  19. }
[cpp]  view plain copy
  1. void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv*  env, jobject thiz, jint w, jint h)  
  2. {  
  3.     if (!cocos2d::CCDirector::sharedDirector()->getOpenGLView())  
  4.     {  
  5.     cocos2d::CCEGLView *view = &cocos2d::CCEGLView::sharedOpenGLView();  
  6.         view->setFrameWidthAndHeight(w, h);  
  7.         view->create(1024,768);  
  8.         // if you want to run in WVGA with HVGA resource, set it  
  9.         // view->create(480, 320);  Please change it to (320, 480) if you're in portrait mode.  
  10.         cocos2d::CCDirector::sharedDirector()->setOpenGLView(view);  
  11.   
  12.         AppDelegate *pAppDelegate = new AppDelegate();  
  13.         cocos2d::CCApplication::sharedApplication().run();  
  14.     }  
  15.     else  
  16.     {  
  17.         cocos2d::CCTextureCache::reloadAllTextures();  
  18.         cocos2d::CCDirector::sharedDirector()->setGLDefaultValues();  
  19.     }  
  20. }  

这样,就可以了,不管andriod是什么分辨率,使用了这个方法后,都会自动调整,一切ok。

好了,现在总结一下

用第三种方法固然后,但是也有弊端,譬如说程序本来是支持1024*768的,然后我们要改成800*480的,宽和高是不成比例的,所以用这种方法后,在x轴上会有黑边。

如果要全屏的效果,那只能用第一种方法,做多套资源处理之。

你可能感兴趣的:(cocos2d-x 屏幕自适应解决办法)