我们的游戏已经很像游戏了(像?敢情它真的不是一个游戏?),于是我们给主角加点吃的吧,老是这么跑,没有追求啊喂~
1.
画点吃的物体
现在,我们又要打开我们的地图编辑器,把下面的星星作为可以吃的物品画到barrier地图层上:
看看我的画吧,依旧有大师风范~噗
2.
添加“另类”障碍物。
其实,吃的物品,也可以当成是障碍物,只不过这个障碍物和主角碰撞之后会消失,仅此而已。
于是,我们和之前描红格子的方式一样,不过,这次我们要描蓝色格子,选择图块上的蓝色格子,噢,抱歉,它是绿色的= =。右键,属性,我们给绿色格子添加一个属性,叫做“star”,属性值为true。
然后,我们把地图切换到meta层,在上面用绿色格子把我们的所有星星都覆盖~效果如下:
3.
让主角把星星吃掉
其实大家到这里应该早就知道接下来该怎么做了,是吧,不过我还是稍微啰嗦一下哈。
打开我们Player.cpp的setSimplePosition函数,以前我们只是取得主角当前所在地图格子的属性里的Collidable属性值,这次我们还要再多获取一个值,那就是star的属性值。函数稍微修改了一些,并且加了一些容错机制:
01 |
void Player::setSimplePosition( int x, inty ) |
02 |
03 |
{ |
04 |
05 |
/* -----------------判断是否不可通行---------------- */ |
06 |
07 |
/* 获得当前主角在地图中的格子位置 */ |
08 |
09 |
CCPoint tiledPos = tileCoordForPosition(ccp(x,y)); |
10 |
11 |
/* 获取地图格子的唯一标识 */ |
12 |
13 |
int tiledGid = meta->tileGIDAt(tiledPos); |
14 |
15 |
/* 不为0,代表存在这个格子 */ |
16 |
17 |
if (tiledGid != 0) { |
18 |
19 |
/* |
20 |
21 |
获取该地图格子的所有属性,目前我们只有一个Collidable属性, |
22 |
23 |
格子是属于meta层的,但同时也是属于整个地图的,所以在获取格子的所有属性时, |
24 |
25 |
通过格子唯一标识在地图中取得。 |
26 |
27 |
*/ |
28 |
29 |
CCDictionary* propertiesDict = map->propertiesForGID(tiledGid); |
30 |
31 |
if (propertiesDict !=NULL) { |
32 |
33 |
const CCString* prop = CCString::create( "" ); |
34 |
35 |
/* 取得格子的Collidable属性值,判断Collidable属性是否为true,是的话,不让玩家移动 */ |
36 |
37 |
prop = propertiesDict->valueForKey( "Collidable" ); |
38 |
39 |
if (prop->length() > 0 &&prop->m_sString.compare( "true" ) == 0) { |
40 |
41 |
if (x > 0) { |
42 |
43 |
x -= 1; |
44 |
45 |
} |
46 |
47 |
else { |
48 |
49 |
x += 1; |
50 |
51 |
} |
52 |
53 |
if (y > 0) { |
54 |
55 |
y -= 1; |
56 |
57 |
} |
58 |
59 |
else { |
60 |
61 |
y += 1; |
62 |
63 |
} |
64 |
65 |
} |
66 |
67 |
/* 取得格子的star属性值,判断是否为true,是的话,让格子上的物体消失 */ |
68 |
69 |
prop = propertiesDict->valueForKey( "star" ); |
70 |
71 |
if (prop->length() > 0 &&prop->m_sString.compare( "true" ) == 0) { |
72 |
73 |
/* 从障碍物层清除当前格子的物体 */ barrier->removeTileAt(tiledPos); |
74 |
75 |
} |
76 |
77 |
} |
78 |
79 |
} |
80 |
81 |
Entity::setSimplePosition(x,y); |
82 |
83 |
/* 以主角为中心移动地图 */ |
84 |
85 |
setViewPointByPlayer(); |
86 |
87 |
} |
做法和之前的红色格子是一样的,不多说了,已经注释了。这次说明一点,我加了一个barrier变量,就是我们的障碍层,加到Entity类里:
01 |
class Entity : public CCNode, public ControllerListener { |
02 |
03 |
public : |
04 |
05 |
void setSprite(CCSprite* mSprite); |
06 |
07 |
void setController(Controller* controller); |
08 |
09 |
/* 实现SimpleMoveListener接口的方法 */ |
10 |
11 |
virtual void setSimplePosition(intx,inty); |
12 |
13 |
virtual CCPoint getCurPosition(); |
14 |
15 |
protected : |
16 |
17 |
CCSprite* mSprite; |
18 |
19 |
Controller* mController; |
20 |
21 |
/* map本来是在Player类的,现在我们放在这里 */ |
22 |
23 |
CCTMXTiledMap* map; |
24 |
25 |
/* 检测碰撞的地图层 */ |
26 |
27 |
CCTMXLayer* meta; |
28 |
29 |
/* 障碍物层 */ |
30 |
31 |
CCTMXLayer* barrier; |
32 |
33 |
/* 将像素坐标转换为地图格子坐标*/ |
34 |
35 |
CCPoint tileCoordForPosition(CCPoint pos); |
36 |
37 |
}; |
然后在Player.cpp的initWithTiledMap函数里给barrier赋值:
01 |
/* 加载对象层的所有对象 */ |
02 |
03 |
CCTMXObjectGroup* objGroup = map->objectGroupNamed( "objects" ); |
04 |
05 |
/* 加载meta层 */ |
06 |
07 |
meta = map->layerNamed( "meta" ); |
08 |
09 |
meta->setVisible( false ); |
10 |
11 |
/* 加载障碍物层 */ |
12 |
13 |
barrier = map->layerNamed( "barrier" ); |
OK了,编译运行,当主角经过星星时就会吃掉它,啊,不过,只是吃掉部分而已。这个不是很好,但是,暂时就这么做吧。
对了,我们有没有发现,现在主角是在星星和石头的下面的?这是图层次序问题,我们做一个小改动就好了,打开Player.cpp的initWithTiledMap函数,添加主角精灵到地图的时候增加一个order参数:
Ctrl+Enter 发布
发布
取消