最近在做一个cocos2d-x下的CCTable,希望能模仿UITableView的效果,但是遇到一个问题被卡住了。

我使用CCLayerColor来实现这个CCTable,因为CCLayerColor可以设置layer的大小,而CCLayer是不能设置的。

但问题是CCLayerColor是继承自CCLayer的,而CCLayer没有明确的边界概念,所以超出设定的边界的内容(如添加在layer中的CCSprite)仍然会显示在画面上,不会被隐藏掉。而这一点和UITableView的效果是不一样的。

为了解决这个问题,我在网上搜索了一些资料。结果找到有一个别人已经做好的cocos2d版的CCTableView。(链接:http://www.cocos2d-iphone.org/archives/943)

然后我debug了一下他的代码,发现里面只有一段代码是用来实现隐藏功能的。代码如下:

 1         GLfloat planeTop[]    = {0.0f, -1.0f, 0.0f, viewSize_.height};
2 GLfloat planeBottom[] = {0.0f, 1.0f, 0.0f, 0.0f};
3 GLfloat planeLeft[] = {1.0f, 0.0f, 0.0f, 0.0f};
4 GLfloat planeRight[] = {-1.0f, 0.0f, 0.0f, viewSize_.width};
5
6 glClipPlanef(GL_CLIP_PLANE0, planeTop);
7 glClipPlanef(GL_CLIP_PLANE1, planeBottom);
8 glClipPlanef(GL_CLIP_PLANE2, planeLeft);
9 glClipPlanef(GL_CLIP_PLANE3, planeRight);
10 glEnable(GL_CLIP_PLANE0);
11 glEnable(GL_CLIP_PLANE1);
12 glEnable(GL_CLIP_PLANE2);
13 glEnable(GL_CLIP_PLANE3);

目前我还不了解这段代码的执行机制,但它确实有效果。因此我决定把这段代码移植到我的CCTable中。

由于原作者对CCNode做过一些修改。他在CCNode中添加了beforeDraw()和afterDraw()两个方法,并且在CCNode的visit()方法中添加了两句调用这两个方法的代码。修改后代码如下:

 1     if (!visible_)
2 return;
3
4 glPushMatrix();
5
6 if ( grid_ && grid_.active) {
7 [grid_ beforeDraw];
8 [self transformAncestors];
9 }
10
11 [self transform];
12 [self beforeDraw];
13 for (CCNode * child in children_) {
14 if ( child.zOrder < 0 )
15 [child visit];
16 else
17 break;
18 }
19
20 [self draw];
21
22 for (CCNode * child in children_) {
23 if ( child.zOrder >= 0 )
24 [child visit];
25 }
26 [self afterDraw];
27 if ( grid_ && grid_.active)
28 [grid_ afterDraw:self];
29
30 glPopMatrix();

因此我在移植时候也需要做同样的修改。

最后在CCTable中继承CCNode的beforeDraw()和afterDraw()方法,将控制隐藏超出内容的代码加入到beforeDraw()中。再将恢复opengl设置的代码放在afterDraw()中:

1         glDisable(GL_CLIP_PLANE0);
2 glDisable(GL_CLIP_PLANE1);
3 glDisable(GL_CLIP_PLANE2);
4 glDisable(GL_CLIP_PLANE3);

完成后,编译调试一切正常,CCTable也有了将超出部分隐藏的功能。

posted on 2011-12-16 12:08  eagley  阅读(9106)  评论(3编辑  收藏  举报