Cocos2d iPhone - 精灵剪辑/蒙版/帧

14

如何在Cocos2D中剪裁/裁剪/遮罩或设置CCSprite的帧?

类似于:使用clippingSubviews = TRUE为UIView设置框架

我的CCSprite Main Sprite 有多个Child Sprite添加到其中。 我只想让该主要的Sprite的部分Mask可见。是否有一种方法可以剪切或使用蒙版来处理CCSprite?

我可以切掉背景,将其放在顶部,仅留下该可见区域,但那是唯一的方法吗?!

以下是演示我想实现的示例图像: alt text
(来源:dnamique.com

3个回答

15

我最终使用了GL_SCISSOR。

在MainSprite中,我实现了:

- (void) visit
{
    if (!self.visible) {
        return;
    }
    glEnable(GL_SCISSOR_TEST);
    glScissor(x, y, width, height);   
    [super visit];
    glDisable(GL_SCISSOR_TEST);
}

这将截取或遮罩指定的区域。

唯一棘手的部分是,在横屏模式下,Cocos2D的0,0位于屏幕的左下角,而OpenGL将其视为屏幕右下角,因为它不考虑屏幕的方向。

换句话说,对于OpenGL来说,您需要考虑一个旋转的纵向屏幕。


还有一个需要注意的地方 - 剪辑区域不是相对于精灵的,而是基于世界坐标系。因此,无论您如何变换精灵,它都将保持在原地。如果您需要移动遮罩,则必须手动移动/缩放它以与精灵一起移动。 - jtalarico
是的,你说得对。一开始我没有意识到这一点。现在我将x和y相对于我的视图位置进行了调整,所以它们会一起移动。 - Bach
@jtalarico,你知道在使用CCDirector::sharedDirector()->pushScene( CCTransitionSlideInL::create( 10.0f, pScene ) );进行过渡时如何获取精灵变换吗?谢谢! - Zennichimaro

11
我写了一个ClippingNode类来实现这个功能。您可以向ClippingNode添加其他节点(精灵、标签等),它们将只在ClippingNode指定的区域内绘制。它还考虑到设备旋转。
在内部,它使用GL_SCISSOR_TEST,就像Bach的答案中所示。
参考链接:http://www.learn-cocos2d.com/2011/01/cocos2d-gem-clippingnode/

你如何处理旋转的裁剪节点? - docchang

3

我尝试使用Steffen Itterheim的ClippingNode,但无法以足够健壮的方式满足我的需求。

信不信由你,下面的代码表现相当不错,应该是完整的代码。它处理设备方向变化、锚点、位置、缩放(scaleX、scaleY)。对于cocos2d v2,您可能只需要注释掉glPushMatrix和glPopMatrix调用。

使用时,只需设置position和contentSize属性并将子项添加到此ClippingNode实例中即可。contentSize属性用于定义剪切区域的尺寸。

example of usage:
ClippingNode *clipNode = [[ClippingNode alloc] init];
clipNode.anchorPoint = ccp(0.5f, 0);
clipNode.position = ccp(100, 25);
clipNode.contentSize = CGSizeMake(120, 120);

// add clipNode to your node hierarchy.
[parentNode addChild:clipNode];

// add one or more children to your clipNode:
[clipNode addChild:child1];

// ClippingNode.h
// CC0 - (public domain. Use in anyway you see fit.)
// No warranty of any kind is expressed or implied.
//
// by UChin Kim.
//
// the caller can simply set the regular cocos2d
// properties: position and contentSize to define the clipping region implicitly (i.e. the
// position and contentSize of the ClippingNode is the clipping region to be used).
// as an added bonus, position seems to work as expected (relative to parent node, instead of
// requiring absolute positioning).
//
// also, anchorPoint and scale properties seem to work as expected as well..
// no special code is neeed to handle device orientation changes correctly..
//
// To visually see exactly what is being clipped, set the following #define
// #define SHOW_CLIPPED_REGION_IN_LIGHT_RED 1
//

#import "cocos2d.h"

@interface ClippingNode : CCNode

@end

//
// ClippingNode.m
//
#import "ClippingNode.h"

@implementation ClippingNode

-(void) visit
{
CGPoint worldOrg = [self convertToWorldSpace:ccp(0, 0)];
CGPoint dest = [self convertToWorldSpace:ccp(self.contentSize.width, self.contentSize.height)];
CGPoint dims = ccpSub(dest, worldOrg);

glPushMatrix();
glEnable(GL_SCISSOR_TEST);

glScissor(worldOrg.x, worldOrg.y, dims.x, dims.y);

#if SHOW_CLIPPED_REGION_IN_LIGHT_RED
glColor4ub(64, 0, 0, 128);
ccDrawSolidRect(ccp(0, 0), ccp(1024, 1024));
#endif

[super visit];

glDisable(GL_SCISSOR_TEST);
glPopMatrix();
}

@end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接