cocos2d-x 1.0版本 自适应屏幕分辨率
最近需要把IOS上的一款游戏移植到Android平台,该游戏使用的cocos2d-x版本是cocos2d-1.0.1-x-0.12.0,由于美术太忙,没法提供android平台的图片,没办法暂时就只能用ipad的图片了,图片的尺寸是1024×768。我想要实现的效果是:图片资源能根据手机实际的分辨率自动缩放,由于只有一套图片没法在各分辨率全屏显示,可以接受两侧留黑边。在网上找到一个不错的实现方案,本文内容主要参考这篇博客,地址:
http://www.jb51.cc/article/p-tgpzreum-yw.html,。原理其实比较简单:计算手机屏幕宽高跟图片资源的宽高比(手机屏幕宽度/图片宽度、手机屏幕高度/图片高度,宽高都以像素为单位),然后计算缩放因子进行缩放,因为需要保证图片全部显示到屏幕内,所以缩放倍数要大,缩放因子要小。
下面来实现一个demo,图片资源使用的是cocos2dx-2.0.4版本例子中的1024×768的图片,首先创建一个ViewAutoScale.h:
下面来实现一个demo,图片资源使用的是cocos2dx-2.0.4版本例子中的1024×768的图片,首先创建一个ViewAutoScale.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#ifndef VIEW_AUTO_SCALE_H
#define VIEW_AUTO_SCALE_H
#include "cocos2d.h"
int
ViewAutoScale(cocos2d::CCEGLView* view,
void
* title,
int
width,
int
height,
cocos2d::CCSize* supportDisplay,
int
displays,
int
defaultWidth,
int
defaultHeight);
inline
bool
IsMatchDisplay(
int
w,
int
h,cocos2d::CCSize& size)
{
return
(w==size.width && h==size.height) || (h==size.width && w==size.height);
}
#endif
|
创建ViewAutoScale.cpp,实现各个平台的缩放功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
#include "ViewAutoScale.h"
using
namespace
cocos2d;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
int
ViewAutoScale(cocos2d::CCEGLView* view,
int
defaultHeight)
{
if
(view == NULL)
{
return
-1;
}
for
(
int
i=0; i < displays; i++)
{
if
(IsMatchDisplay(width,height,supportDisplay[i]))
{
view->Create((
LPCTSTR
)title,width,height);
return
i+1;
}
}
view->Create((
LPCTSTR
)title,defaultWidth,defaultHeight);
view->setScreenScale(min((
float
)width/ defaultWidth,(
float
)height/ defaultHeight));
view->resize(width,height);
view->centerWindow();
return
0;
}
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
int
ViewAutoScale(cocos2d::CCEGLView* view,
void
* title,
int
width,
int
height,
cocos2d::CCSize* supportDisplay,
int
displays,
int
defaultWidth,
int
defaultHeight)
{
if
(view == NULL)
{
return
-1;
}
for
(
int
i=0; i < displays; i++)
{
if
(IsMatchDisplay(width,supportDisplay[i]))
{
return
i+1;
}
}
view->create(defaultWidth,defaultHeight);
return
0;
}
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
int
ViewAutoScale(cocos2d::CCEGLView* view,
void
* title,
int
width,
int
height,
cocos2d::CCSize* supportDisplay,
int
displays,
int
defaultWidth,
int
defaultHeight)
{
return
0;
}
#endif
|
接着要在各个平台进行调用了:
(1) Win32平台
在AppDelegate.cpp的AppDelegate::initInstance()里添加:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
// Initialize OpenGLView instance,that release by CCDirector when application terminate.
// The HelloWorld is designed as HVGA.
#define GAME_WIDTH 960
#define GAME_HEIGHT 540
#define DEFAULT_WIDTH 1024
#define DEFAULT_HEIGHT 768
CCSize sSupportDisplay[] = {CCSize(1024,768)};
CCEGLView * pMainWnd =
new
CCEGLView();
CC_BREAK_IF(! pMainWnd);
if
(ViewAutoScale(pMainWnd,TEXT(
"IQ:960x540"
),
GAME_WIDTH,
GAME_HEIGHT,
sSupportDisplay,
sizeof
(sSupportDisplay)/
sizeof
(CCSize),
DEFAULT_WIDTH,DEFAULT_HEIGHT) < 0)
{
return
false
;
}
#endif // CC_PLATFORM_WIN32
|
sSupportDisplay为你的游戏能支持的分辨率,就是准备的图片的尺寸。DEFAULT_WIDTH和DEFAULT_HEIGHT表示游戏默认使用的图片尺寸,如果游戏运行的机器屏幕不在准备的范围内,就以默认的值为基数进行缩放。下面是在各分辨率下运行的效果,1024×768刚好跟图片尺寸一样,效果是完美的,刚好全屏,这里就不贴出了。在博客上看到的图片可能是变形的,是为了避免图片超出网页边框,就对图片宽度进行了压缩,真实的图片是没有变形的。
960×540:
800×480:
(2)android平台
修改/jni/helloworld/main.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
void
Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env,jobject thiz,jint w,jint h)
{
cocos2d::CCSize sSupportDisplay[] = { cocos2d::CCSize(1024,768) };
if
(!cocos2d::CCDirector::sharedDirector()->getOpenGLView())
{
cocos2d::CCEGLView *view = &cocos2d::CCEGLView::sharedOpenGLView();
view->setFrameWidthAndHeight(w,h);
// if you want to run in WVGA with HVGA resource,set it
// view->create(480,320); Please change it to (320,480) if you're in portrait mode.
ViewAutoScale(view,NULL,w,h,sSupportDisplay,
sizeof
(sSupportDisplay) /
sizeof
(CCSize),1024,768);
cocos2d::CCDirector::sharedDirector()->setOpenGLView(view);
AppDelegate *pAppDelegate =
new
AppDelegate();
cocos2d::CCApplication::sharedApplication().run();
}
else
{
cocos2d::CCTextureCache::reloadAllTextures();
cocos2d::CCDirector::sharedDirector()->setGLDefaultValues();
}
}
|
下图是800×480分辨率模拟器上的效果:
如果你需要游戏能全屏显示的话,就选择缩放倍数小的值,即缩放因子大的值,修改ViewAutoScale.cpp:
1
2
3
|
view->setScreenScale(min((
float
)width/ defaultWidth,(
float
)height/ defaultHeight));
//改成
view->setScreenScale(max((
float
)width/ defaultWidth,(
float
)height/ defaultHeight));
|
运行到android平台还需要修改引擎的源码,因为引擎默认使用的是min方式,修改platform\android\CCEGLView_android.cpp的CCEGLView::create(int width,int height)函数:
1
2
3
4
5
|
m_fScreenScaleFactor = MIN((
float
)m_sSizeInPixel.width / m_sSizeInPoint.width,
(
float
)m_sSizeInPixel.height / m_sSizeInPoint.height);
//改成
m_fScreenScaleFactor = MAX((
float
)m_sSizeInPixel.width / m_sSizeInPoint.width,
(
float
)m_sSizeInPixel.height / m_sSizeInPoint.height);
|
下面是CCEGLView::create(int width,int height)函数的完整源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
void
CCEGLView::create(
int
width,
int
height)
{
if
(width == 0 || height == 0)
{
return
;
}
m_sSizeInPoint.width = width;
m_sSizeInPoint.height = height;
// calculate the factor and the rect of viewport
m_fScreenScaleFactor = MIN((
float
)m_sSizeInPixel.width / m_sSizeInPoint.width,
(
float
)m_sSizeInPixel.height / m_sSizeInPoint.height);
int
viewPortW = (
int
)(m_sSizeInPoint.width * m_fScreenScaleFactor);
int
viewPortH = (
int
)(m_sSizeInPoint.height * m_fScreenScaleFactor);
m_rcViewPort.origin.x = (m_sSizeInPixel.width - viewPortW) / 2;
m_rcViewPort.origin.y = (m_sSizeInPixel.height - viewPortH) / 2;
m_rcViewPort.size.width = viewPortW;
m_rcViewPort.size.height = viewPortH;
m_bNotHVGA =
true
;
}
|
demo源码下载地址:http://download.csdn.net/detail/zhoujianghai/4814684