精灵地图和精灵的顶点顺序

时间:2013-09-24 04:10:28

标签: cocos2d-iphone

这是设置。我有一个用Tiled制作的正交瓷砖地图。共有5层。底部4包括背景,而顶层是前景,我将其称为“树”层。我有一个英雄精灵,我作为树图的子节点添加到与树图层相同的节点zorder。

这个场景总是出现的问题是,我希望我的英雄在树下,他在“下面”,但在那些树后面,他“在上面”。下方和上方由英雄的Y坐标与任何给定树的Y坐标确定。

Cocos2d编程指南包含一个用于平铺贴图的部分,在该部分中,它专门讨论了如何实现我所描述的效果。这些信息可以在这里找到。

http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:tiled_maps

解决方案非常简单。在我的代码中启用深度缓冲区。向英雄将在其上的每个图层添加值为-1000的cc_vertexz属性。然后将cc_vertexz属性添加到树层,其值为“automatic”以及值为.5的cc_alpha_func属性。然后当你的英雄移动时,根据它在地图中的位置重新调整其精灵的vertexz值。

我做了这一切,效果很好。但是,一旦我将其他“敌人”精灵添加到此地图中,就会出现问题。与英雄精灵一样,这些精灵被添加到具有与树图层相同的节点zorder的地图中,并且它们的顶点值也根据其在地图中的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。此外,如果启用了自动vertexz,这似乎由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,或者我只是做错了什么?我怀疑后者。

非常感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

这已经解决了。解决方案是在我的精灵或精灵表上使用以下内容,视情况而定:

mySprite.shaderProgram = [[CCShaderCache sharedShaderCache]programForKey:kCCShader_PositionTextureColorAlphaTest];

这基本上取代了CCSprite的子类化并覆盖了draw方法,这是Cocos2d 1.x的规定方法,而我使用的是Cocos2d 2.x.