这是装置。我有一张用瓷砖做的正交瓷砖地图。有5层。下面4构成背景,而最上层是前景,我将称之为“树”层。我有一个英雄精灵,我在与树层相同的节点zorder中添加了一个瓷砖地图的子元素。
问题总是出现在这个场景中,我希望我的英雄站在他“下面”的树前,但在那些树的后面,他却“在上面”。下面和上面是由英雄的Y坐标和任意给定树的Y坐标决定的。
Cocos2d编程指南包含一个贴片映射部分,在这一节中它专门讨论了如何实现我所描述的影响。这些信息可以在这里找到。
maps
解决办法很简单。在我的代码中启用深度缓冲区。向英雄将在上面的每个层添加一个值为-1000的cc_vertexz属性。然后向树层添加一个cc_vertexz属性,其值为“automatic”,以及一个值为.5的cc_alpha_func属性。然后,当你的英雄移动时,根据它在地图中的位置,重新调整它的顶点值。
这一切都是我干的,效果很好。然而,当我在这张地图上添加其他“敌人”精灵时,问题就出现了。与英雄精灵一样,这些精灵被添加到地图中,与树层具有相同的节点zorder,并且它们的顶点值也根据映射中的Y坐标而改变。应该注意的是,英雄精灵是在敌人精灵之后添加的。此外,英雄和敌人的精灵都是动画,他们的纹理不是贴图纹理的一部分。根据Cocos2d文档,这不重要。
问题是这个。如果我的英雄在地图上的敌人精灵下面,那么一切看起来都很好。然而,如果我的英雄在地图上的敌人精灵之上,那么当敌人经过英雄精灵时,背景就会出现,而不是英雄精灵。最好的说法是,一旦敌人的精灵开始越过英雄精灵,敌人精灵的透明区域就开始充满背景,英雄精灵被部分遮蔽,直到敌人精灵离开英雄。就像英雄精灵不存在一样。
我知道这与精灵被添加到地图上的顺序有关,因为如果我改变这一点,在敌人精灵之前把英雄精灵添加到地图上,那么效果就会逆转,因为背景来自英雄精灵的透明区域,而不是敌人精灵。几乎就像vertexz属性不能绝对决定绘制的顺序一样。
从这个角度来看,这似乎是一个混合问题,我发现了一个似乎是解决方案的方法,即对CCSprite类进行子类化,并使用以下方法覆盖with方法:
-(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,还是我只是做错了什么?我怀疑后者。
任何帮助都将不胜感激。谢谢!
发布于 2013-09-25 19:21:35
这个问题已经解决了。解决办法是在我的精灵或精灵片上(视情况而定)使用以下方法:
mySprite.shaderProgram = [[CCShaderCache sharedShaderCache]programForKey:kCCShader_PositionTextureColorAlphaTest];这实际上取代了子类CCSprite和重写绘图方法,后者是Cocos2d 1.x的指定方法,而我使用的是Cocos2d 2.x。
https://stackoverflow.com/questions/18972827
复制相似问题