完美主义情况下android自适屏,最好的方式当然是做多套不同分辨率屏幕大小的图片资源,但是一般作为我们这样的小团队开发,不会去花费太多的时间去做多套不同的资源,能给你多做几个封面就不错了,所以这个重任又从美术的头上落到我们程序猿的头上,在cocos2d-x中android包默认支持等比例的屏幕缩放,具体实现方式,在jni/helloworld/main.cpp中增加如下代码即可。继续拿HelloWorld开刀!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
void
Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit
(
JNIEnv
*
env
,
jobject
thiz
,
jint
w
,
jint
h
)
{
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.
view
->
create
(
480
,
320
)
;
// 增加此句即可,480*320是你的游戏标准大小
cocos2d
::
CCDirector
::
sharedDirector
(
)
->
setOpenGLView
(
view
)
;
AppDelegate
*
pAppDelegate
=
new
AppDelegate
(
)
;
cocos2d
::
CCApplication
::
sharedApplication
(
)
.
run
(
)
;
}
else
{
cocos2d
::
CCTextureCache
::
reloadAllTextures
(
)
;
cocos2d
::
CCDirector
::
sharedDirector
(
)
->
setGLDefaultValues
(
)
;
}
}
|
这样游戏就已经等比缩放了,不过在大部分android手机上会有黑边,虽然我个人比较喜欢这种方式,因为等比缩放游戏画面不会变形,但是通常情况下我说是没用的,策划说要全屏的,测试说要全屏的,我说让美术做个图,美术说要约会,没时间加班,好吧。又成了程序员的事了。
上面说过cocos2d-x默认支持等比例缩放,从源代码可以看出来,这些源代码在cocos2dx/platform/android下面,在CCEGLView_android.cpp中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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
;
}
|
在CCEGLView_android中增加宽高不同的缩放参数,并使用这两个参数来对画面进行不等比缩放
CCEGLView_android.h中增加
1
2
3
4
5
6
7
8
9
|
float
getScreenScaleFactor
(
)
;
// Hxs add for non uniform scale. 2013/05/15
float
getScreenScaleFactorX
(
)
;
float
getScreenScaleFactorY
(
)
;
/*********************/
float
m_fScreenScaleFactor
;
// 原本只有一个缩放参数,等比缩放会有黑边
// Hxs add for non uniform scale. 2013/05/15
float
m_fScreenScaleFactorX
;
// X,Y方向的缩放参数
float
m_fScreenScaleFactorY
;
|
CCEGLView_android.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
77
|
#define NON_UNIFORM_SCALE 1 // 不等比缩放开关 宏定义
/* 修改create(int width, int height) / CCEGLView::setViewPortInPoints(float x, float y, float w, float h) / CCEGLView::setScissorInPoints(float x, float y, float w, float h)方法中关于缩放的处理 */
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
)
;
#if NON_UNIFORM_SCALE
m_fScreenScaleFactorX
=
(
float
)
m_sSizeInPixel
.
width
/
m_sSizeInPoint
.
width
;
// 分别得到X,Y的缩放参数
m_fScreenScaleFactorY
=
(
float
)
m_sSizeInPixel
.
height
/
m_sSizeInPoint
.
height
;
#else
m_fScreenScaleFactorX
=
m_fScreenScaleFactor
;
// 等比例缩放
m_fScreenScaleFactorY
=
m_fScreenScaleFactor
;
#endif
int
viewPortW
=
(
int
)
(
m_sSizeInPoint
.
width
*
m_fScreenScaleFactorX
)
;
int
viewPortH
=
(
int
)
(
m_sSizeInPoint
.
height
*
m_fScreenScaleFactorY
)
;
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
;
}
void
CCEGLView
::
setViewPortInPoints
(
float
x
,
float
y
,
float
w
,
float
h
)
{
if
(
m_bNotHVGA
)
{
float
factorX
=
m_fScreenScaleFactorX
/
CC_CONTENT_SCALE_FACTOR
(
)
;
float
factorY
=
m_fScreenScaleFactorY
/
CC_CONTENT_SCALE_FACTOR
(
)
;
glViewport
(
(
GLint
)
(
x
*
factorX
)
+
m_rcViewPort
.
origin
.
x
,
(
GLint
)
(
y
*
factorY
)
+
m_rcViewPort
.
origin
.
y
,
(
GLint
)
(
w
*
factorX
)
,
(
GLint
)
(
h
*
factorY
)
)
;
}
else
{
glViewport
(
(
GLint
)
x
,
(
GLint
)
y
,
(
GLint
)
w
,
(
GLint
)
h
)
;
}
}
void
CCEGLView
::
setScissorInPoints
(
float
x
,
float
y
,
float
w
,
float
h
)
{
if
(
m_bNotHVGA
)
{
float
factorX
=
m_fScreenScaleFactorX
/
CC_CONTENT_SCALE_FACTOR
(
)
;
float
factorY
=
m_fScreenScaleFactorY
/
CC_CONTENT_SCALE_FACTOR
(
)
;
glScissor
(
(
GLint
)
(
x
*
factorX
)
+
m_rcViewPort
.
origin
.
x
,
(
GLint
)
(
y
*
factorY
)
+
m_rcViewPort
.
origin
.
y
,
(
GLint
)
(
w
*
factorX
)
,
(
GLint
)
(
h
*
factorY
)
)
;
}
else
{
glScissor
(
(
GLint
)
x
,
(
GLint
)
y
,
(
GLint
)
w
,
(
GLint
)
h
)
;
}
}
/* 增加getScreenScaleFactorX/getScreenScaleFactorY的实现 */
float
CCEGLView
::
getScreenScaleFactorX
(
)
{
return
m_fScreenScaleFactorX
;
}
float
CCEGLView
::
getScreenScaleFactorY
(
)
{
return
m_fScreenScaleFactorY
;
}
|
到此为止,画面上的缩放已经完成啦,但是缩放后触摸的位置还需要修正,继续修改cocos2dx/platform/android/jni/TouchesJni.cpp中关于触摸的缩放,此文件中有多处需要修改的敌方,但是修改方式都一样。以Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeTouchesBegin为例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
void
Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeTouchesBegin
(
JNIEnv
*
env
,
jobject
thiz
,
jint
id
,
jfloat
x
,
jfloat
y
)
{
CCRect
rcRect
=
CCEGLView
::
sharedOpenGLView
(
)
.
getViewPort
(
)
;
//float fScreenScaleFactor = CCEGLView::sharedOpenGLView().getScreenScaleFactor();
float
fScreenScaleFactorX
=
CCEGLView
::
sharedOpenGLView
(
)
.
getScreenScaleFactorX
(
)
;
float
fScreenScaleFactorY
=
CCEGLView
::
sharedOpenGLView
(
)
.
getScreenScaleFactorY
(
)
;
CCSet
set
;
CCTouch
*
pTouch
=
s_pTouches
[
id
]
;
if
(
!
pTouch
)
{
LOGD
(
"Beginning touches with id: %d, x=%f, y=%f"
,
id
,
x
,
y
)
;
pTouch
=
new
CCTouch
(
)
;
//pTouch->SetTouchInfo(0, (x - rcRect.origin.x) / fScreenScaleFactor, (y - rcRect.origin.y) / fScreenScaleFactor, id);
// 分别对x 和 y进行缩放
pTouch
->
SetTouchInfo
(
0
,
(
x
-
rcRect
.
origin
.
x
)
/
fScreenScaleFactorX
,
(
y
-
rcRect
.
origin
.
y
)
/
fScreenScaleFactorY
,
id
)
;
s_pTouches
[
id
]
=
pTouch
;
set
.
addObject
(
pTouch
)
;
cocos2d
::
CCDirector
::
sharedDirector
(
)
->
getOpenGLView
(
)
->
getDelegate
(
)
->
touchesBegan
(
&set
,
NULL
)
;
}
else
{
LOGD
(
"Beginnig touches with id: %d error"
,
id
)
;
}
}
|