这是设置。我有一个用 Tiled 制作的正交瓷砖地图。有5层。底部 4 层是背景,而顶层是前景,我将其称为“树”层。我有一个英雄精灵,我在与树层相同的节点 zorder 处添加了作为瓦片地图的子项。
这种情况总是会出现的问题是,我希望我的英雄在他“下方”的树前,但在他“上方”的那些树后面。下方和上方由英雄的 Y 坐标与任何给定树的 Y 坐标确定。
Cocos2d 编程指南包含一个关于瓦片地图的部分,在该部分中它专门讨论了如何实现我所描述的效果。可以在此处找到此信息。
http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:tiled_maps
解决方案非常简单。在我的代码中启用深度缓冲区。为英雄所在的每一层添加一个值为 -1000 的 cc_vertexz 属性。然后向树层添加一个值为“自动”的 cc_vertexz 属性以及一个值为 0.5 的 cc_alpha_func 属性。然后当你的英雄移动时,根据它在地图中的位置重新调整它的 sprite 的 vertexz 值。
我做了这一切,效果很好。然而,当我在这张地图上添加其他“敌人”精灵时,问题就出现了。与英雄精灵一样,这些精灵以与树层相同的节点 zorder 添加到地图中,并且它们的 vertexz 值也根据它们在地图中的 Y 坐标而改变。需要注意的是,英雄精灵是在敌人精灵之后添加的。此外,英雄和敌人的精灵都是动画的,它们的纹理不是瓷砖贴图纹理的一部分。根据 Cocos2d 文档,这无关紧要。
问题是这样的。如果我的英雄在地图上的敌方精灵下方,那么一切看起来都很好。但是,如果我的英雄在地图上的敌方精灵上方,那么当敌人越过英雄精灵时,背景会穿过而不是英雄精灵。最好的描述方式是,一旦敌方精灵开始越过英雄精灵,敌方精灵的透明区域开始被背景填充,英雄精灵被部分遮挡,直到敌方精灵离开英雄。就像英雄精灵不存在一样。
我知道这与精灵添加到地图的顺序有关,因为如果我改变它并在敌人精灵之前将英雄精灵添加到地图中,那么效果会反转,因为背景来自透明区域英雄精灵而不是敌人精灵。就好像 vertexz 属性并不能绝对决定事物的绘制顺序。
调查这似乎是一个混合问题,我发现似乎是解决方案,即子类化 CCSprite 类并使用以下内容覆盖 draw 方法:
-(void) draw {
glEnable(GL_ALPHA_TEST);
glAlphaFunc( GL_GREATER, 0 );
[super draw];
glDisable(GL_ALPHA_TEST);
}
但问题是这段代码不适用于我使用的 Cocos2d 版本,即 Cocos2d 2.1。此外,如果启用了自动顶点,这似乎由 CCTMXLayer 绘图功能处理。因此,我不知道子类化 CCSprite 是否只是多余的。有关 CCTMXLayer 如何处理此问题,请参见下文:
// CCTMXLayer drawing function -(void) draw
{
if( useAutomaticVertexZ_ ) {
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, alphaFuncValue_);
}
[super draw];
if( useAutomaticVertexZ_ )
glDisable(GL_ALPHA_TEST);
}
我对 Cocos2d 并不陌生,但我对与 OpenGL 相关的任何事物都很陌生。所以简而言之,解决方案只是将 CCSprite 子类化并找到与上述代码片段等效的 Cocos2d 2.1,还是我只是做错了什么?我怀疑是后者。
任何帮助将不胜感激。谢谢!