Cocos2d中的旋转剪切节点

时间:2012-12-28 18:06:59

标签: cocos2d-iphone clipping ccnode

我在这里使用剪切节点:http://www.learn-cocos2d.com/2011/01/cocos2d-gem-clippingnode

ClippingNode.h

#import "cocos2d.h"
@interface ClippingNode : CCNode {
    CGRect clippingRegionInNodeCoordinates;
    CGRect clippingRegion;
}
@property (nonatomic) CGRect clippingRegion;
@end

ClippingNode.m

#import "ClippingNode.h"

@interface ClippingNode (PrivateMethods)
-(void) deviceOrientationChanged:(NSNotification*)notification;
@end

@implementation ClippingNode
-(CGRect) clippingRegion {
    return clippingRegionInNodeCoordinates;
}

-(void) setClippingRegion:(CGRect)region {

    // keep the original region coordinates in case the user wants them back unchanged
    clippingRegionInNodeCoordinates = region;
    self.position = clippingRegionInNodeCoordinates.origin;
    self.contentSize = clippingRegionInNodeCoordinates.size;

    // convert to retina coordinates if needed
    region = CC_RECT_POINTS_TO_PIXELS(region);

    // respect scaling
    clippingRegion = CGRectMake(region.origin.x * scaleX_, region.origin.y * scaleY_,
                            region.size.width * scaleX_, region.size.height * scaleY_);
}

-(void) setScale:(float)newScale {
    [super setScale:newScale];
    // re-adjust the clipping region according to the current scale factor
    [self setClippingRegion:clippingRegionInNodeCoordinates];
}

-(void) deviceOrientationChanged:(NSNotification*)notification {
    // re-adjust the clipping region according to the current orientation
    [self setClippingRegion:clippingRegionInNodeCoordinates];
}

-(void) visit {

    glEnable(GL_SCISSOR_TEST);
    CGPoint worldPosition = [self convertToWorldSpace:CGPointZero];
    const CGFloat s = [[CCDirector sharedDirector] contentScaleFactor];
    glScissor((clippingRegion.origin.x) + (worldPosition.x*s), (clippingRegion.origin.y) + (worldPosition.y*s),
          (clippingRegion.size.width), (clippingRegion.size.height));

    [super visit];

    glDisable(GL_SCISSOR_TEST);

}
@end

但是,我需要剪切旋转的CCNode。关于如何完成这项任务的任何想法?

2 个答案:

答案 0 :(得分:2)

用此

替换ClippingNode类中的visit方法
-(void) visit
{

    float rotationAngle = 15;

    glPushMatrix();

    CCRenderTexture* renderTexture = [[CCRenderTexture renderTextureWithWidth:512 height:512] retain];

    glEnable(GL_SCISSOR_TEST);
    glScissor(0, 0, clippingRegion.size.width, clippingRegion.size.height);

    [renderTexture begin];

    glPushMatrix();
    glRotatef(rotationAngle, 0, 0, 1);
    glTranslatef(-clippingRegion.origin.x, -clippingRegion.origin.y, 0);

    [super visit];

    glPopMatrix();

    [renderTexture end];

    glDisable(GL_SCISSOR_TEST);

    renderTexture.sprite.position = CGPointMake(clippingRegion.origin.x , clippingRegion.origin.y);
    renderTexture.sprite.anchorPoint = CGPointMake(0, 1);
    renderTexture.sprite.rotation = rotationAngle;
    [renderTexture.sprite visit];

    [renderTexture release];

    glPopMatrix();
}

基本上它会创建一个纹理,用于呈现ClippingNode内容

然后翻译场景,使裁剪区域中的原点现在为(0,0)

通过rotationAngle

旋转整个场景

启用剪刀

渲染场景

翻译,旋转和渲染包含纹理的精灵

enter image description here

答案 1 :(得分:0)

只需要CCRenderTexture即可完成这项工作。任何建议将不胜感激。

ClippingNode.h

#import "cocos2d.h"
@interface ClippingNode : CCNode
@property (nonatomic, assign) CGSize clippingSize;
@end

ClippingNode.m

#import "ClippingNode.h"
@interface ClippingNode()
@property (nonatomic, strong) CCRenderTexture * renderTexture;
@property (nonatomic, strong) CCSprite * clippedSprite;
@end


@implementation ClippingNode
@synthesize renderTexture;
@synthesize clippedSprite;
@synthesize clippingSize;

- (void) setClippingSize:(CGSize)newClippingSize {

    //assignment
    clippingSize = newClippingSize;

    //set contentSize
    self.contentSize = clippingSize;

    //configure renderTexture
    self.renderTexture = [CCRenderTexture renderTextureWithWidth:clippingSize.width height:clippingSize.height];
    renderTexture.contentSize = CGSizeMake(clippingSize.width, clippingSize.height);

    //configure the renderTexture sprite
    self.clippedSprite = [CCSprite spriteWithTexture:renderTexture.sprite.texture];
    clippedSprite.position = self.position;
    clippedSprite.rotation = rotation_;
    clippedSprite.scaleY = -1;
}

- (void)visit {
    [renderTexture beginWithClear:0 g:0 b:0 a:1];
    [super visit];
    [renderTexture end];

    [clippedSprite visit];
}

@end

用法:

CCSprite * spriteImage = ...;
spriteImage.position = ccp(0,0);
spriteImage.anchorPoint = ccp(0.5,0.5);

//configure clipping Node
self.clippingNode = [ClippingNode node];
clippingNode.position = ccp(size.width * 0.5f, size.height * 0.5f);
clippingNode.anchorPoint = ccp(0.5f, 0.5f);
clippingNode.rotation = -10.0f;

//configure clipping region
[clippingNode setClippingSize:CGSizeMult(spriteImage.boundingBox.size, 1.5f)];

//add content to the clipping node
[clippingNode addChild:spriteImage]