0

这是设置。我有一个用 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,还是我只是做错了什么?我怀疑是后者。

任何帮助将不胜感激。谢谢!

4

1 回答 1

0

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

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

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

于 2013-09-25T19:21:35.747 回答