总结了下,新手引导的要点有以下几个:
下面我们就详细讲述这几个要点:
对个这个不同的游戏的做法不尽相同,归结起来大概有这么几种:
1.画面整体变暗
这个比较简单,cocos2d就有现成接口:
1
2
3
4
5
|
CCSize
visibleSize
=
CCDirector
::
sharedDirector
(
)
->
getVisibleSize
(
)
;
//第一个参数是颜色ccc4(r,g,b,a) a取值(0~255),越大越不透明 下面两个参数为宽高,不传默认为屏幕大小
CCLayerColor
*
pLayer
=
CCLayerColor
::
create
(
ccc4
(
0
,
0
,
0
,
200
)
,
visibleSize
.
width
,
visibleSize
.
height
)
;
//CCLayerColor* pLayer=CCLayerColor::create(ccc4(0,0,0,200));
addChild
(
pLayer
,
100
)
;
|
效果如下:
然后你可以在这层之上添加精灵,最后的效果可能是这个样子的:
注:图片源自网络,如果有版权问题~你丫去死吧! 请联系我!
2.局部高亮
比较简单的方法是准备几张张局部高亮的图片,随着引导进度变化而切换!优点是可以做的比较精美,缺点是资源量会比较大!另一种方法是在画面整体变暗的基础上抠掉部分区域,还好cocos2d提供了CCClippingNode接口(2.1+版)!
CCClippingNode类比较复杂,但我们只用明白两个东西就好:一个是CCClippingNode的Stencil,一个CCClippingNode的Child,怎么理解呢?请看下图:
这个东西相信大家都有印象吧,上面的图案(镂空部分)就是 CCClippingNode的Stencil(模板),实体部分就是CCClippingNode的child(底板),是不是很好明白,让我们用代码来实现吧:
1
2
3
4
5
6
|
//创建cliper对象
CCClippingNode
*
pClip
=
CCClippingNode
::
create
(
)
;
addChild
(
pClip
)
;
//加入灰色的底板
CCLayerColor
*
pColor
=
CCLayerColor
::
create
(
ccc4
(
0
,
0
,
0
,
200
)
)
;
pClip
->
addChild
(
pColor
)
;
|
让我来加入模板:
1
2
3
4
5
6
7
8
9
10
|
//创建drawnode对象
CCDrawNode
*
m_pAA
=
CCDrawNode
::
create
(
)
;
static
ccColor4F
green
=
{
0
,
1
,
0
,
1
}
;
static
CCPoint
rect
[
4
]
=
{
ccp
(
-
50
,
50
)
,
ccp
(
50
,
50
)
,
ccp
(
50
,
-
50
)
,
ccp
(
-
50
,
-
50
)
}
;
//用上面的数据保存一个100x100的矩形
m_pAA
->
drawPolygon
(
rect
,
4
,
green
,
0
,
green
)
;
//设置到屏幕的中心
m_pAA
->
setPosition
(
ccp
(
visibleSize
.
width
/
2
+
origin
.
x
,
visibleSize
.
height
/
2
+
origin
.
y
)
)
;
//设置为pclip的模板
pClip
->
setStencil
(
m_pAA
)
;
|
CCDrawNode是用来绘制几何图形的,drawPolygon使用绘制多边形,参数为顶点数组,顶点数量,边框宽度,和填充颜色!这里要注意一点:千万不要addChild(m_pAA);因为一旦addchild,m_pAA就会被绘制出来,我们是要用它做剪裁!他会在CCClippingNode内部被使用!
我们会看到这样的效果:
额,貌似和我们想想的不太一样啊,为什么呢?那是因为CCClippingNode有一个选项是是否反向,既显示Stencil呢还是child减去Stencil的部分!默认为显示显示镂空(Stencil)部分(false),因此我们要改变选项:
1
2
|
//是否反向?
pClip
->
setInverted
(
true
)
;
|
效果如下,是不是很棒:
3.组合效果(将2的矩形改成圆,再加上图片)
让我们先看这张图片,是不是很棒?右下角黄色矩形区域是高亮的,在配上图片说明,很不错的效果!
让我们来实现类似的效果吧,用到的资源:
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
|
//创建cliper
CCClippingNode
*
pClip
=
CCClippingNode
::
create
(
)
;
pClip
->
setInverted
(
true
)
;
addChild
(
pClip
)
;
//添加底板
CCLayerColor
*
pColor
=
CCLayerColor
::
create
(
ccc4
(
0
,
0
,
0
,
200
)
)
;
pClip
->
addChild
(
pColor
)
;
//绘制圆形区域
static
ccColor4F
green
=
{
0
,
1
,
0
,
1
}
;
//顶点颜色,这里我们没有实质上没有绘制,所以看不出颜色
float
fRadius
=
55.0f
;
//圆的半径
const
int
nCount
=
100
;
//圆形其实可以看做正多边形,我们这里用正100边型来模拟园
const
float
coef
=
2.0f
*
(
float
)
M_PI
/
nCount
;
//计算每两个相邻顶点与中心的夹角
static
CCPoint
circle
[
nCount
]
;
//顶点数组
for
(
unsigned
int
i
=
0
;
i
<
nCount
;
i
++
)
{
float
rads
=
i
*
coef
;
//弧度
circle
[
i
]
.
x
=
fRadius
*
cosf
(
rads
)
;
//对应顶点的x
circle
[
i
]
.
y
=
fRadius
*
sinf
(
rads
)
;
//对应顶点的y
}
CCDrawNode
*
pStencil
=
CCDrawNode
::
create
(
)
;
pStencil
->
drawPolygon
(
circle
,
nCount
,
green
,
0
,
green
)
;
//绘制这个多边形!
//动起来
pStencil
->
runAction
(
CCRepeatForever
::
create
(
CCSequence
::
createWithTwoActions
(
CCScaleBy
::
create
(
0.05f
,
0.95f
)
,
CCScaleTo
::
create
(
0.125f
,
1
)
)
)
)
;
pStencil
->
setPosition
(
ccp
(
visibleSize
.
width
/
2
+
origin
.
x
,
visibleSize
.
height
/
2
+
origin
.
y
)
)
;
//设这模板
pClip
->
setStencil
(
pStencil
)
;
//添加圆和手的图片
CCSprite
*
pCircle
=
CCSprite
::
create
(
"circle.png"
)
;
pCircle
->
setPosition
(
ccp
(
visibleSize
.
width
/
2
+
origin
.
x
,
visibleSize
.
height
/
2
+
origin
.
y
)
)
;
pCircle
->
runAction
(
CCRepeatForever
::
create
(
CCSequence
::
createWithTwoActions
(
CCScaleBy
::
create
(
0.05f
,
0.95f
)
,
CCScaleTo
::
create
(
0.125f
,
1
)
)
)
)
;
addChild
(
pCircle
)
;
CCSprite
*
pHand
=
CCSprite
::
create
(
"hand.png"
)
;
pHand
->
setAnchorPoint
(
ccp
(
0.0f
,
1.0f
)
)
;
pHand
->
setPosition
(
ccp
(
pCircle
->
getContentSize
(
)
.
width
/
2
,
pCircle
->
getContentSize
(
)
.
height
/
2
)
)
;
pCircle
->
addChild
(
pHand
)
;
|
上面是全部的代码,效果图如下(动态的会更好)没有加圆圈和手之前和之后:
那么如何改变高亮区域得位置呢?很简单,只用改变pStencil的位置即可!可以考虑记为成员变量在ccTouchesBegan中改变位置,这样就会高亮区域就会跟着你的鼠标走啦!
1.开启触摸 阻止穿透响应 判断落点
让我们继续看下面的这张图片:
这张图片中应该只有右下角的”冒险”按钮能够响应的到,那么怎么实现呢?这个要用到我之前的文章 COCOS2D-X 游戏实战经验(一) 触摸响应 中的知识,建议先看下这篇文章,我在这里说下思路:
下面是代码片段:
1).开启触摸
1
2
3
4
5
6
7
8
9
|
bool
CTeachLayer
::
init
(
)
{
if
(
!
CCLayer
::
init
(
)
)
{
return
false
;
}
setTouchEnabled
(
true
)
;
return
true
;
}
|
2).提升触摸响应优先级为-128
1
2
3
4
5
6
|
void
CTeachLayer
::
registerWithTouchDispatcher
(
)
{
//使用-128和CCMenu优先级相同,并且吞掉事件true//
CCDirector
::
sharedDirector
(
)
->
getTouchDispatcher
(
)
->
addTargetedDelegate
(
this
,
-
128
,
true
)
;
CCLayer
::
registerWithTouchDispatcher
(
)
;
}
|
3).在ccTouchBegan判断触点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
bool
CTeachLayer
::
ccTouchBegan
(
CCTouch
*
pTouch
,
CCEvent
*
pEvent
)
{
//得到触摸位置
CCPoint
touchPoint
=
pTouch
->
getLocation
(
)
;
//声明一个右下角100x50的矩形
CCRect
m_obRect
=
CCRectMake
(
CCDirector
::
sharedDirector
(
)
->
getVisibleSize
(
)
.
width
-
100
,
CCDirector
::
sharedDirector
(
)
->
getVisibleSize
(
)
.
height
-
50
,
100
,
50
)
;
//判断点是否在矩形中
if
(
m_obRect
.
containsPoint
(
touchPoint
)
)
{
return
false
;
}
return
true
;
}
|
大功告成,快去试一下吧!
2.精确命中
手机上和电脑上的触摸事件的区别在于:电脑上我们是用鼠标点击,而手机上使用手指去摁,触摸的精度的高低不言而喻!让我们来看下面这张图片:
让我们看右上角的X号按钮,在手机上点击它来说应该是很困难的!他的真实尺寸应该是红色矩形的区域(假设:50×50),为了让玩家在引导时,能够很方便的点击到它,我们将实际的可触摸区域设置为蓝色区域(假设:100×100),这样应该很好点到了吧!
这样会有一个新的问题,如果点击到红色和蓝色之间的区域,下面的x按钮时响应不到的,那么怎么办呢?我们需要修改touch的数据(设置为按钮的正中心),然后touch事件将会以新的数据向下传递!这样下面的按钮就能响应到了!
让我们看看代码吧:
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
|
bool
CTeachLayer
::
ccTouchBegan
(
CCTouch
*
pTouch
,
CCEvent
*
pEvent
)
{
CCPoint
touchPoint
=
pTouch
->
getLocation
(
)
;
if
(
!
CGlobal
::
s_bTeach
)
{
return
false
;
}
//假设按钮在(300,200)的位置,那么蓝色矩形如下:
CCRect
m_obRect
=
CCRectMake
(
250
,
150
,
100
,
100
)
;
if
(
m_obRect
.
containsPoint
(
touchPoint
)
)
{
//得到蓝色矩形的中心点(300,200)
CCPoint
pos
=
ccp
(
m_obRect
.
getMidX
(
)
,
m_obRect
.
getMidY
(
)
)
;
//这里要转化为UI坐标系(左上角为0,0点)
pos
=
CCDirector
::
sharedDirector
(
)
->
convertToUI
(
pos
)
;
//设置触摸信息
pTouch
->
setTouchInfo
(
pTouch
->
getID
(
)
,
pos
.
x
,
pos
.
y
)
;
return
false
;
}
return
true
;
}
|
这里我大概说下新手引导的架构,代码肯定贴不出来,太多太乱,说的不对的地方,欢迎大家拍砖吐槽!>_<
1.首先创建了一个CTeachLayer继承自CCLayer,添加到游戏的最上层(UI层之上),记住,要先添加游戏的其层,最后添加CTeachLayer,可以保存全局指针!
2.用一个枚举记下你要引导的所有步骤,在根据枚举值去设置高亮的位置及触摸区域!可以记下当前引导的进度,以方便下次继续引导!
3.游戏逻辑中免不了要判断引导(例:出第3波怪的时候引导玩家使用清屏道具),用全局的指针去设置引导的步骤!
4.引导完成后移除CTeachLayer,游戏开始!